[javascript] ReactJS : 최대 업데이트 깊이 초과 오류
ReactJS에서 구성 요소의 상태를 전환하려고하는데 오류 메시지가 나타납니다.
최대 업데이트 깊이를 초과했습니다. 이는 구성 요소가 componentWillUpdate 또는 componentDidUpdate 내에서 setState를 반복적으로 호출 할 때 발생할 수 있습니다. React는 무한 루프를 방지하기 위해 중첩 업데이트 수를 제한합니다.
내 코드에 무한 루프가 보이지 않습니다. 누구든지 도울 수 있습니까?
ReactJS 컴포넌트 코드 :
import React, { Component } from 'react';
import styled from 'styled-components';
class Item extends React.Component {
constructor(props) {
super(props);
this.toggle= this.toggle.bind(this);
this.state = {
details: false
}
}
toggle(){
const currentState = this.state.details;
this.setState({ details: !currentState });
}
render() {
return (
<tr className="Item">
<td>{this.props.config.server}</td>
<td>{this.props.config.verbose}</td>
<td>{this.props.config.type}</td>
<td className={this.state.details ? "visible" : "hidden"}>PLACEHOLDER MORE INFO</td>
{<td><span onClick={this.toggle()}>Details</span></td>}
</tr>
)}
}
export default Item;
답변
render 메소드 안에서 토글을 호출하면 다시 렌더링되고 토글이 다시 호출되고 다시 렌더링됩니다.
이 줄은 코드에서
{<td><span onClick={this.toggle()}>Details</span></td>}
당신은 그것을 호출하지 않는 onClick
참조 해야 this.toggle
합니다
이 문제 를 해결 하려면
{<td><span onClick={this.toggle}>Details</span></td>}
답변
함수를 호출 할 때 이벤트 객체를 전달해야합니다.
{<td><span onClick={(e) => this.toggle(e)}>Details</span></td>}
onClick 이벤트를 처리 할 필요가없는 경우 다음을 입력 할 수도 있습니다.
{<td><span onClick={(e) => this.toggle()}>Details</span></td>}
이제 함수 내에 매개 변수를 추가 할 수도 있습니다.
답변
먼저 반응을 잊어라 :
이것은 반응과 관련이 없으며 Java Script의 기본 개념을 이해하도록하자. 예를 들어 Java 스크립트에서 다음 함수를 작성했습니다 (이름은 A).
function a() {
};
Q.1) 정의한 함수를 어떻게 호출합니까?
답변 : a ();
Q.2) 후자를 호출 할 수 있도록 함수 참조를 전달하는 방법은 무엇입니까?
답변 :하자 = a;
이제 당신의 질문에, 당신은 함수 이름과 함께 paranthesis를 사용했습니다. 다음 명령문이 렌더링 될 때 함수가 호출된다는 것을 의미합니다.
<td><span onClick={this.toggle()}>Details</span></td>
그런 다음 수정하는 방법?
단순한!! 괄호를 제거하십시오. 이런 식으로 해당 함수의 참조를 onClick 이벤트에 제공했습니다. 컴포넌트를 클릭 할 때만 함수를 호출합니다.
<td><span onClick={this.toggle}>Details</span></td>
한 가지 제안은 반응에 의존했다 :
답변에서 누군가가 제안한대로 인라인 함수를 사용하지 마십시오. 성능 문제가 발생할 수 있습니다. 다음 코드를 피하십시오. 함수가 호출 될 때마다 동일한 함수의 인스턴스를 반복해서 생성합니다 (lamda 문은 매번 새 인스턴스를 생성합니다).
참고 : 이벤트 (e)를 명시 적으로 함수에 전달할 필요가 없습니다. 전달하지 않고 함수에서 액세스 할 수 있습니다.
{<td><span onClick={(e) => this.toggle(e)}>Details</span></td>}
https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578
답변
나는 이것이 많은 답변을 가지고 있음을 알고 있지만 대부분이 오래 되었기 때문에 (매우 오래 됨), 내가 매우 빠르게 성장하는 접근법을 언급하는 사람은 없습니다. 한마디로 :
기능적 구성 요소와 고리를 사용하십시오 .
더 길게 :
특히 렌더링을 위해 클래스 구성 요소 대신 많은 기능 구성 요소를 사용하고 가능한 한 순수하게 유지하십시오 (예, 기본적으로 데이터는 더럽습니다).
기능적 구성 요소의 두 가지 명백한 이점 (더 많음) :
- 순결 또는 거의 순결은 디버깅을 훨씬 쉽게 만듭니다.
- 기능적인 구성 요소는 생성자 보일러 코드를 필요로하지 않습니다
2 포인트에 대한 빠른 증거-이것이 역겨운가요?
constructor(props) {
super(props);
this.toggle= this.toggle.bind(this);
this.state = {
details: false
}
}
기능 구성 요소를 더 많이 사용하여 렌더링하는 경우 큰 듀오 후크의 두 번째 부분이 필요합니다. 수명주기 방법보다 나은 이유는 무엇입니까? 다른 방법으로 더 많은 것을 처리 할 공간이 많이 필요하므로 남자 자신의 말을 들어 보는 것이 좋습니다 .Dan the hooks
이 경우 두 개의 후크 만 필요합니다.
편리하게 이름이 지정된 콜백 후크 useCallback
. 이렇게하면 다시 렌더링 할 때 함수가 계속 바인딩되는 것을 막을 수 있습니다.
useState
전체 구성 요소가 작동하고 전체를 실행하는 데에도 불구하고 상태를 유지하기위한 이라고하는 상태 후크 (예, 후크의 마법 때문에 가능) 해당 후크 내에 토글 값을 저장합니다.
이 부분을 읽으면 아마도 내가 실제로 이야기하고 원래 문제에 적용한 모든 것을보고 싶을 것입니다. 여기 있습니다 :
데모
구성 요소를 한 눈에보고 싶어하는 사용자에게는 WTF가 다음과 같습니다.
const Item = () => {
// HOOKZ
const [isVisible, setIsVisible] = React.useState('hidden');
const toggle = React.useCallback(() => {
setIsVisible(isVisible === 'visible' ? 'hidden': 'visible');
}, [isVisible, setIsVisible]);
// RENDER
return (
<React.Fragment>
<div style={{visibility: isVisible}}>
PLACEHOLDER MORE INFO
</div>
<button onClick={toggle}>Details</button>
</React.Fragment>
)
};
추신 : 나는 많은 사람들이 비슷한 문제로 여기에 도착하는 경우에 이것을 썼습니다. 바라건대 그들은 적어도 조금 더 구글을 볼 수있을만큼 충분히 좋아하는 것을 좋아할 것입니다. 이것은 다른 답변이 잘못되었다고 말하는 것이 아닙니다. 이것은 그들이 작성된 시간부터 이것을 처리하는 다른 방법 (IMHO, 더 나은 방법)이 있다는 것입니다.
답변
함수에 인수를 전달할 필요가 없으면 아래처럼 함수에서 ()를 제거하십시오.
<td><span onClick={this.toggle}>Details</span></td>
그러나 인수를 전달하려면 다음과 같이해야합니다.
<td><span onClick={(e) => this.toggle(e,arg1,arg2)}>Details</span></td>
답변
ReactJS : 최대 업데이트 깊이 초과 오류
inputDigit(digit){
this.setState({
displayValue: String(digit)
})
<button type="button"onClick={this.inputDigit(0)}>
왜 그런가요?
<button type="button"onClick={() => this.inputDigit(1)}>1</button>
onDigit 함수는 상태를 설정하여 rerender를 발생시킵니다. onDigit가 onClick으로 설정 한 값이기 때문에 onDigit이 실행됩니다.이 경우 상태가 설정되어 rerender가 발생하여 onDigit가 실행됩니다. 다시… 기타
답변
1. 호출에서 인수를 전달하려면 아래처럼 메소드를 호출해야합니다. 화살표 함수를 사용하므로에서 메소드를 바인딩 할 필요가 없습니다 cunstructor
.
onClick={() => this.save(id)}
이렇게 생성자에서 메소드를 바인딩 할 때
this.save= this.save.bind(this);
다음과 같은 인수를 전달하지 않고 메소드를 호출해야합니다.
onClick={this.save}
아래와 같이 함수를 호출하는 동안 인수를 전달하려고하면 최대 깊이를 초과 한 것처럼 오류가 발생합니다.
onClick={this.save(id)}