ReactJS: Warning: setState(…): Cannot update during an existing state transition

后端 未结 11 1072
一个人的身影
一个人的身影 2020-11-27 10:32

I am trying to refactor the following code from my render view:

相关标签:
11条回答
  • 2020-11-27 10:41

    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) }

    0 讨论(0)
  • 2020-11-27 10:43

    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.

    0 讨论(0)
  • 2020-11-27 10:43

    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().

    0 讨论(0)
  • 2020-11-27 10:45

    THE PROBLEM is here: onClick={this.handleButtonChange(false)}

    When you pass this.handleButtonChange(false) to onClick, you are actually calling the function with value = false and setting onClick to the function's return value, which is undefined. Also, calling this.handleButtonChange(false) then calls this.setState() which triggers a re-render, resulting in an infinite render loop.

    THE SOLUTION is to pass the function in a lambda: onClick={() => this.handleButtonChange(false)}. Here you are setting onClick to equal a function that will call handleButtonChange(false) when the button is clicked.

    The below example may help:

    function handleButtonChange(value){
      console.log("State updated!")
    }
    
    console.log(handleButtonChange(false))
    //output: State updated!
    //output: undefined
    
    console.log(() => handleButtonChange(false))
    //output: ()=>{handleButtonChange(false);}
    
    0 讨论(0)
  • 2020-11-27 10:51

    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.

    0 讨论(0)
  • 2020-11-27 10:55

    Looks like you're accidentally calling the handleButtonChange method in your render method, you probably want to do onClick={() => this.handleButtonChange(false)} instead.

    If you don't want to create a lambda in the onClick handler, I think you'll need to have two bound methods, one for each parameter.

    In the constructor:

    this.handleButtonChangeRetour = this.handleButtonChange.bind(this, true);
    this.handleButtonChangeSingle = this.handleButtonChange.bind(this, false);
    

    And in the render method:

    <Button href="#" active={!this.state.singleJourney} onClick={this.handleButtonChangeSingle} >Retour</Button>
    <Button href="#" active={this.state.singleJourney} onClick={this.handleButtonChangeRetour}>Single Journey</Button>
    
    0 讨论(0)
提交回复
热议问题