6

我有一个包含一些数据的表,表中的每个元素都是一个 React 类组件。它看起来像这样:

桌子

我想要的只是有一个用于“全选”功能的复选框(左上角复选框)。问题是我不知道如何解决这个问题,因为propsand state

我在单元素组件中有这样的代码:

getInitialState: function() {
    return { component: this.props.data };
  },

render: function() {
    var data = this.state.component;
    data = data.set('checked', this.props.data.get('checked'));
    ...
}

而且我知道我不应该从中获取checked参数,props但这只是暂时的。

我遇到的问题是:当我更新checked父级中的参数时,它不会更新状态,因为getInitialState在刷新后不会调用(是的,我知道它应该是这样的)。

我的问题是:我可以以某种方式更新子组件的状态吗?或者这是实现这一目标的更好方法。

4

4 回答 4

9

使用功能组件: 当父级更改提供的道具时,刷新子级内部状态的简单方法是通过useEffect()

在孩子们:

const [data, setData] = useState(props.data);

useEffect( () => {
    setData(props.data);
}, [props.data]); 

这样,每次props.data更改都会触发 useEffect 并强制为某些数据设置新状态,因此组件将“刷新”。

于 2020-12-13T11:20:33.617 回答
7

我的方法是你应该在父母的渲染中有这样的结构:

<ParentView>
{ this.props.rows.map(function(row) {
    <ChildRow props={row.props} />
  }).bind(this)
}
</ParentView>

然后row.props你就知道当前行项目是否被选中。当父复选框被切换时,您将使用状态填充所有 row.props。

在孩子身上,你会收到那些,componentWillReceiveProps当复选框被切换时你会做魔法(例如设置正确的状态):

componentWillReceiveProps: function(props) {
  this.setState({isChecked: props.isChecked});
}

(来自 React 文档的信息:在此函数中调用 this.setState() 不会触发额外的渲染。

子元素的渲染将类似于:

<div>
  <input type='checkbox' checked={this.state.isChecked} />
  <label>{this.props.label}</label>
</div>
于 2015-04-24T13:45:44.293 回答
3

您可以通过仅将所有子元素的选中状态存储在父元素中来解决此问题。孩子们只根据道具设置他们的检查状态(他们不为此使用状态)并调用父母提供的回调来改变这一点。

例如,在孩子身上:

render: function() {
    //... not showing other components...
        <input type="checkbox"
               value={this.props.value}
               checked={this.props.checked}
               onClick={this.props.onClick}>
}

父级提供onClick,它会更改子级在其状态下的已检查状态,并在重新渲染时将其传递回给子级。

在父级中:

getInitialState: function() {
    return {
        allChecked: false,
        childrenChecked: new Array(NUM_CHILDREN) // initialise this somewhere (from props?)
    }
},

render: function() {
    return <div>
               <input type="checkbox" checked={this.state.allChecked}>
               {children.map(function(child, i) {
                   return <Child checked={this.state.childrenChecked[i]}
                                 onClick={function(index) {
                                     return function() {
                                         // update this.state.allChecked and this.state.childrenChecked[index]
                                     }.bind(this)
                                 }.bind(this)(i)}
                          />
                }).bind(this)}
           </div>;
}

-- 不检查错别字等。

于 2015-04-24T13:52:52.350 回答
2

请参阅关于提升状态的反应文档。在您的子组件中,您需要使用道具。要更新道具,您需要从父级提供更新功能。

于 2017-11-30T00:02:36.640 回答