ReactJS : 경고 : setState (…) : 기존 상태 전환 중에 업데이트 할 수 없습니다
렌더 뷰에서 다음 코드를 리팩토링하려고합니다.
<Button href="#" active={!this.state.singleJourney} onClick={this.handleButtonChange.bind(this,false)} >Retour</Button>
바인드가 생성자 내에있는 버전으로. 그 이유는 렌더 뷰에서 바인드가 저급 휴대 전화에서 성능 문제를 발생시키기 때문입니다.
다음 코드를 만들었지 만 끊임없이 다음과 같은 오류 (많은 오류)가 발생합니다. 앱이 반복되는 것처럼 보입니다.
Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.
아래는 내가 사용하는 코드입니다.
var React = require('react');
var ButtonGroup = require('react-bootstrap/lib/ButtonGroup');
var Button = require('react-bootstrap/lib/Button');
var Form = require('react-bootstrap/lib/Form');
var FormGroup = require('react-bootstrap/lib/FormGroup');
var Well = require('react-bootstrap/lib/Well');
export default class Search extends React.Component {
constructor() {
super();
this.state = {
singleJourney: false
};
this.handleButtonChange = this.handleButtonChange.bind(this);
}
handleButtonChange(value) {
this.setState({
singleJourney: value
});
}
render() {
return (
<Form>
<Well style={wellStyle}>
<FormGroup className="text-center">
<ButtonGroup>
<Button href="#" active={!this.state.singleJourney} onClick={this.handleButtonChange(false)} >Retour</Button>
<Button href="#" active={this.state.singleJourney} onClick={this.handleButtonChange(true)} >Single Journey</Button>
</ButtonGroup>
</FormGroup>
</Well>
</Form>
);
}
}
module.exports = Search;
실수로 handleButtonChange렌더 메소드에서 메소드를 호출하는 것 같습니다 onClick={() => this.handleButtonChange(false)}. 대신에 원할 수도 있습니다.
onClick 핸들러에서 람다를 생성하지 않으려면 각 매개 변수마다 하나씩 두 개의 바인딩 된 메소드가 필요하다고 생각합니다.
에서 constructor:
this.handleButtonChangeRetour = this.handleButtonChange.bind(this, true);
this.handleButtonChangeSingle = this.handleButtonChange.bind(this, false);
그리고 render방법에서 :
<Button href="#" active={!this.state.singleJourney} onClick={this.handleButtonChangeSingle} >Retour</Button>
<Button href="#" active={this.state.singleJourney} onClick={this.handleButtonChangeRetour}>Single Journey</Button>
I am giving a generic example for better understanding, In the following code
render(){
return(
<div>
<h3>Simple Counter</h3>
<Counter
value={this.props.counter}
onIncrement={this.props.increment()} <------ calling the function
onDecrement={this.props.decrement()} <-----------
onIncrementAsync={this.props.incrementAsync()} />
</div>
)
}
When supplying props I am calling the function directly, this wold have a infinite loop execution and would give you that error, Remove the function call everything works normally.
render(){
return(
<div>
<h3>Simple Counter</h3>
<Counter
value={this.props.counter}
onIncrement={this.props.increment} <------ function call removed
onDecrement={this.props.decrement} <-----------
onIncrementAsync={this.props.incrementAsync} />
</div>
)
}
If you are trying to add arguments to a handler in recompose, make sure that you're defining your arguments correctly in the handler. It is essentially a curried function, so you want to be sure to require the correct number of arguments. This page has a good example of using arguments with handlers.
Example (from the link):
withHandlers({
handleClick: props => (value1, value2) => event => {
console.log(event)
alert(value1 + ' was clicked!')
props.doSomething(value2)
},
})
for your child HOC and in the parent
class MyComponent extends Component {
static propTypes = {
handleClick: PropTypes.func,
}
render () {
const {handleClick} = this.props
return (
<div onClick={handleClick(value1, value2)} />
)
}
}
this avoids writing an anonymous function out of your handler to patch fix the problem with not supplying enough parameter names on your handler.
From react docs Passing arguments to event handlers
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
This same warning will be emitted on any state changes done in a render() call.
An example of a tricky to find case: When rendering a multi-select GUI component based on state data, if state has nothing to display, a call to resetOptions() is considered state change for that component.
The obvious fix is to do resetOptions() in componentDidUpdate() instead of render().
I got the same error when I was calling
this.handleClick = this.handleClick.bind(this);
in my constructor when handleClick didn't exist
(I had erased it and had accidentally left the "this" binding statement in my constructor).
Solution = remove the "this" binding statement.
The problem is certainly the this binding while rending the button with onClick handler. The solution is to use arrow function while calling action handler while rendering. Like this: onClick={ () => this.handleButtonChange(false) }
The solution that I use to open Popover for components is reactstrap (React Bootstrap 4 components).
class Settings extends Component {
constructor(props) {
super(props);
this.state = {
popoversOpen: [] // array open popovers
}
}
// toggle my popovers
togglePopoverHelp = (selected) => (e) => {
const index = this.state.popoversOpen.indexOf(selected);
if (index < 0) {
this.state.popoversOpen.push(selected);
} else {
this.state.popoversOpen.splice(index, 1);
}
this.setState({ popoversOpen: [...this.state.popoversOpen] });
}
render() {
<div id="settings">
<button id="PopoverTimer" onClick={this.togglePopoverHelp(1)} className="btn btn-outline-danger" type="button">?</button>
<Popover placement="left" isOpen={this.state.popoversOpen.includes(1)} target="PopoverTimer" toggle={this.togglePopoverHelp(1)}>
<PopoverHeader>Header popover</PopoverHeader>
<PopoverBody>Description popover</PopoverBody>
</Popover>
<button id="popoverRefresh" onClick={this.togglePopoverHelp(2)} className="btn btn-outline-danger" type="button">?</button>
<Popover placement="left" isOpen={this.state.popoversOpen.includes(2)} target="popoverRefresh" toggle={this.togglePopoverHelp(2)}>
<PopoverHeader>Header popover 2</PopoverHeader>
<PopoverBody>Description popover2</PopoverBody>
</Popover>
</div>
}
}
'Programming' 카테고리의 다른 글
| 종속 DLL이 Visual Studio의 빌드 출력 폴더로 복사되지 않습니다 (0) | 2020.05.24 |
|---|---|
| 기존 JavaScript 라이브러리에서 .d.ts "typings"정의 파일을 어떻게 생성합니까? (0) | 2020.05.24 |
| SQL 절“GROUP BY 1”은 무엇을 의미합니까? (0) | 2020.05.24 |
| Node.js 로깅 (0) | 2020.05.24 |
| 정수 범위를 지정하여 최적화 프로그램에 힌트를 줄 수 있습니까? (0) | 2020.05.24 |