代码之家  ›  专栏  ›  技术社区  ›  Craig

更新处于状态的子节点中的值

  •  0
  • Craig  · 技术社区  · 7 年前

    我的状态中有类似于下面json对象的数据:

    {
      "ID": "1234",
      "Name": "Craig",
      "Children": [
        {
          "Name": "Jim",
          "Id": "1",
          "Enabled": true
        },
        {
          "Name": "Sam",
          "Id": "2",
          "Enabled": false
        },
        {
          "Name": "Donald",
          "Id": "3",
          "Enabled": true
        }
      ]
    }
    

    所以,如果我把Jim改成false,我会传回{1和false}。。

    然后,这就是我被卡住的地方,我需要在我的状态中找到子对象,并更改Enabled值。

    var child = (from c in state.data.Children where c.Id = 1);
    

    然后设置该值。 (child.enabled = newValue) .

    或者,我用更新后的值siply回发整个props值,然后在父组件中,用新值替换整个“Children”对象。这似乎是一个坏主意,因为我会改变整个子节点,为一个小的变化。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Daniel Lizik    7 年前

    有几种方法可以做到这一点,我会通过道具给子组件传递一个闭包。这使得子数组非常“愚蠢”,不必担心它在父数组中的位置。

    class Container extends Component {
      handleOnChange = (index) => () => {
        this.setState({
          data: data.map((node, i) => index !== i 
            ? node 
            : ({ ...node, Enabled: !node.Enabled }))
        });
      }
    
      render() {
        return (
          <Fragment>
            {this.state.data.Children.map((child, i) => (
              <ChildDataNode isEnabled={child.Enabled} onChange={this.handleOnChange(i)} />
            ))}
          </Fragment>
        );
      }
    }
    
    // child
    const ChildDataNode = ({ isEnabled, onChange }) => (
      <div>
        <input type="checkbox" onChange={onChange} value={isEnabled} />
      </div>
    );
    

    做同样的事而不治疗 handleOnChange 作为结束,这就足够了:

    class Container extends Component {
      handleOnChange = (index) => {
        this.setState({
          data: data.map((node, i) => index !== i 
            ? node 
            : ({ ...node, Enabled: !node.Enabled }))
        });
      }
    
      render() {
        return (
          <Fragment>
            {this.state.data.Children.map((child, i) => (
              <ChildDataNode index={i} isEnabled={child.Enabled} onChange={this.handleOnChange} />
            ))}
          </Fragment>
        );
      }
    }
    
    // child
    const ChildDataNode = ({ isEnabled, onChange, index }) => (
      <div>
        <input type="checkbox" onChange={onChange(index)} value={isEnabled} />
      </div>
    );
    

    六比一,六比一。我更喜欢前一种方法,因为它使孩子尽可能地保持沉默。

        2
  •  0
  •   Hemadri Dasari    7 年前

    您需要将id和enabled值传递给回调事件处理程序,并在事件处理程序函数中为局部变量指定上一个数据子级状态。然后,在子对象上进行映射,并进行id匹配和覆盖对象。

    import React, { Component } from 'react';
    class App extends Component {
      constructor(props){
        super(props);
        this.state={
          data: {
            "ID": "1234",
            "Name": "Craig",
            "Children": [
              {
                "Name": "Jim",
                "Id": "1",
                "Enabled": true
              },
              {
                "Name": "Sam",
                "Id": "2",
                "Enabled": false
              },
              {
                "Name": "Donald",
                "Id": "3",
                "Enabled": true
              }
            ]
          };
        }
      }
    
      //callback function
      handleCheckbox = (id, enabled) => {
        let children = this.state.data.Children;
        let rows = [];
        children.map((d, i) => {
          if(id == d.Id){
            let obj = {};
            obj.Enabled = enabled;
            obj.Id = id;
            obj.Name = d.Name;
            rows.push(obj);
          }else{
            rows.push(d);
          }
        });
    
        this.setState({
          data.Children : rows
        });
      }
      render() {
        return (
          <div>
    
          </div>
        );
      }
    }
    
    export default App;