2

I'm facing a very weird issue here. I'm using react-toggle dependency to just return true/false values of some inputs.

Basically what I'm doing is that I'm using the callback function of the react-toggle inputs to update the values of my react state. For some reason it will only update the last input that have been changed and the others will go false.

Here is how my code looks:

RandomComponent.js

<ToggleComponent title="TestA"/>
<ToggleComponent title="TestB"/>
<ToggleComponent title="TestC"/>
<ToggleComponent title="TestD"/>

ToggleComponent.js

constructor(props){
  super(props);
  this.state={
    testA:false,
    testB:false,
    testC:false,
    testD:false,
  }
}
updateCheckValue(title){
  if(title === 'TestA'){
    this.setState({
      testA: !this.state.testA
    }, ()=>{
      console.log(this.state)
    })
  }
  if(title === 'TestB'){
    this.setState({
      testB: !this.state.testB
    }, ()=>{
      console.log(this.state)
    })
  }
  if(title === 'TestC'){
    this.setState({
      testC: !this.state.testC
    }, ()=>{
      console.log(this.state)
    })
  }
  if(title === 'TestD'){
    this.setState({
      testD: !this.state.testD
    }, ()=>{
      console.log(this.state)
    })
  }
}

render(){
  return(
    <Row className={styles.container}>
        <Col sm={1} md={1} lg={1}></Col>
        <Col sm={2} md={2} lg={2}>
          <Toggle
            onChange={this.updateCheckValue.bind(this, this.props.title)}
            icons={false} />
        </Col>
        <Col sm={8} md={8} lg={8}>
          <h4>{this.props.title}</h4>          
        </Col>
        <Col sm={1} md={1} lg={1}></Col>          
    </Row>
  )
}
Emmanuel
  • 2,957
  • 3
  • 14
  • 17
  • Is setState being called on the parent? If it is then a new instance of the component is being created, which could be causing your issue. You can check this by logging the componentWillMount function of your component to see if it is being fired during your callback – Alex Nov 27 '17 at 15:01
  • @Alex, setState is not being called on the parent. – Emmanuel Nov 27 '17 at 15:14
  • I'm not seeing the values on the components being set from state... like ``. Is that a feature of the component? Or the missing bit of code? – Ted Nov 27 '17 at 15:15

1 Answers1

5

You should change the approach here, the state should be managed by the RandomComponent.js, ToggleComponent.js should call a callback every time it's called. The result should be something like this: RandomComponent.js

constructor(props){
  super(props);
  this.state={
    testA:false,
    testB:false,
    testC:false,
    testD:false,
  }
}
updateCheckValue(att){
    this.setState({
      [att]: !this.state[att]
    }, ()=>{
      console.log(this.state)
    })
  }
}

render(){
    <ToggleComponent title="TestA" onToggle={() => this.updateCheckValue("testA")}/>
    <ToggleComponent title="TestB" onToggle={() => this.updateCheckValue("testB")/>
    <ToggleComponent title="TestC" onToggle={() => this.updateCheckValue("testC")/>
    <ToggleComponent title="TestD" onToggle={() => this.updateCheckValue("testD")/>
}

ToggleComponent.js

<Row className={styles.container}>
    <Col sm={1} md={1} lg={1}></Col>
    <Col sm={2} md={2} lg={2}>
      <Toggle
        onChange={this.props.onToggle}
        icons={false} />
    </Col>
    <Col sm={8} md={8} lg={8}>
      <h4>{this.props.title}</h4>          
    </Col>
    <Col sm={1} md={1} lg={1}></Col>          
</Row>
  • 1
    The state should be managed by the parent that is the one that knows all 4: testA, testB, testC and testD. TestA only knows itself, and can not change the state of TestB, C or D. – Juan Martin Gallo Nov 27 '17 at 15:36