在组件之间正确进行数据管理

时间:2019-05-07 14:09:33

标签: reactjs

我有两个组成部分(父母和孩子)。父组件呈现许多子组件(卡)和页面的常规结构。每张卡都有唯一的ID。

每张卡都有一个复选框,并且该复选框的初始状态应该为false。我想与父组件动态共享复选框的状态。因此,基本上,当我选中或取消选中“卡片”复选框时,我想知道父组件中哪个卡片被选中或未选中。

父母

this.state = {
        isChecked: false // I shouldn't set false?
    }

onChange = (val) => {
    this.setState({isChecked : val})
}

return results.map(card => {
        return <Card isChecked={this.state.isChecked} onChange={this.onChange}/>
    })

卡片(儿童)

this.state = {
        isChecked: false // I shouldn't set false?
    }

handleOnChange = () => {
    this.setState({isChecked: !this.state.isChecked})
    this.props.onChange(this.state.isChecked);
}

<input type="checkbox" onChange={(e) => {this.handleOnChange()}} />

3 个答案:

答案 0 :(得分:0)

将索引值作为prop传递,然后在您检查时将其作为第二个参数传递给索引,那么您将在子组件中收到id,因此在onChange函数的父组件中,您将收到已检查的输入索引。 父母

this.state = {
        isChecked: false // I shouldn't set false?
    }

onChange = (val,index) => {
    this.setState({isChecked : val})
}

return results.map((card,index) => {
        return <Card isChecked={this.state.isChecked} onChange={this.onChange} 
               checkboxId={index} />
    })

卡片(儿童)

handleOnChange = () => {
   this.props.onChange(!this.props.isChecked,this.props.checkboxId);
}

<input type="checkbox" onChange={(e) => {this.handleOnChange()}} />

答案 1 :(得分:0)

You don't need to pass isChecked: false,这是可行的解决方案。

// Parent component
class Parent extends React.Component {
  state = {
    cardArray: [],
    results: [1, 2, 4, 5]
  };
  componentDidMount() {
    let updatedArray = [];
    this.state.results.forEach((result, index) => {
      let checkboxObj = { index: "", isChecked: false };
      checkboxObj.index = index;
      updatedArray.push(checkboxObj);
    });
    this.setState({ cardArray: updatedArray });
  }
  onChange = (value, index) => {
    let updatedArray = this.state.cardArray;
    updatedArray.forEach(result => {
      if (result.index === index) result.isChecked = value;
    });
    console.log(updatedArray);
    this.setState({ cardArray: updatedArray });
  };

  render() {
    let results = this.state.results;
    return results.map((card, index) => {
      return (
        <Card
          index={index}
          isChecked={this.state.isChecked}
          onChange={value => this.onChange(value, index)}
        />
      );
    });
  }
}

//Child component

class Card extends React.Component {

  handleOnChange = (event) => {
    this.props.onChange(event.target.checked);
  };

  render() {
    return (
      <React.Fragment>
        <label>{this.props.index}</label>
        <input
          type="checkbox"
          onChange={event => {
            this.handleOnChange(event);
          }}
        />
      </React.Fragment>
    );
  }
}

ReactDOM.render(<Parent />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root' />

答案 2 :(得分:0)

由于每张卡都是独立的,所以每张卡都应具有自己的isChecked属性。

为了让您知道哪些卡已被选中,哪些卡未被选中,您必须在父组件本身中保持卡的状态 ,并且还应该向下传递{{ 1}}方法传递给子级,以便每当选中或取消选中一张卡时,父级的状态都可以更改。

父项:

onChange

子组件:

class Parent extends React.Component {
  state = {
    results: [
      {
        id: 1
      },
      {
        id: 2
      },
      {
        id: 3
      }
    ]
  };

  // Recursively adding isChecked property on each Card
  componentDidMount() {
    const updatedResults = this.state.results.map(card => {
      card["isChecked"] = false;
      return card;
    })
    this.setState({
      results: updatedResults
    })
  }

      onChange = id => {
        let newResults = this.state.results.map(card => {
              if (card.id === id) {
                 card.isChecked = !card.isChecked;
          }
          return card;
        });
        this.setState({
          results: newResults
        });
      };

  render() {
    const cards = this.state.results.map(card => {
      return <Card card={card} onChange={id => this.onChange(id)} />;
    });
    return <div>{cards}</div>;
  }
}

工作示例here