我是新来的人,可以做出反应并进行还原.
我有一个容器,用于初始化带有项目列表和onclick函数的表组件.
在表格组件中,每行都有一个复选框.当我单击复选框时,我想选择该行(更改其样式并将所选属性添加到其元素模型).
当我单击复选框时,我调用onclick属性函数,然后通过其ID在列表中找到该项目,并更改其选定的属性.该视图没有刷新.
我知道一个组件是一个“愚蠢的”组件,仅绑定了道具和渲染.
我究竟做错了什么?
// People container
<Table items={this.props.people} columns={this._columns} onRowSelect={this.selectRow} />
this.selectRow(id){
const selectedLead =_.find(this.props.leads.docs, (lead)=>{
return lead._id == id;
})
selectedLead.selected = !selectedLead.selected;
}
// Table Component - inside render()
{this.props.items.map((item, idx) => {
console.log(item.selected);
return <div style={styles.row(item.selected)}>etc...</div>
})}
谢谢 :)
解决方法:
React组件具有道具和状态.
不同之处在于,该组件永远不会更改其道具.但是它可以改变它的状态.这就是组件将为您提供setState(…)方法但没有setProps(…)方法的原因.
如此说来,您更改this.props中选定字段的方法从根本上是不正确的. (您的代码中似乎还存在另一个问题,即您更改了this.props.leads中的选定字段,但将this.props.people提供给了表而不是this.props.leads).
让我给您一个基本的示例,说明如何在Pure React中解决您的问题(没有像Redux这样的状态库):
const Row = ({ item, onClick }) => (
<tr style={styles.row(item.selected)} onClick={() => onClick(item.id)}>...</tr>
)
const Table = ({ items, onRowClick }) => (
<table>
{items.map(item => <Row item={item} onClick={onRowClick} />)}
</table>
)
class PeopleTable extends React.PureComponent {
constructor(props) {
super(props)
this.state = { people: props.people }
}
componentWillReceiveProps(nextProps) {
if (nextProps.people !== this.state.people) {
this.setState({ people: nextProps.people })
}
}
setItemSelectedState(id) {
this.setState((prevState) => {
const people = prevState.people.map(item => ({
...item,
selected: item.id === id ? !item.selected : item.selected,
})
return { people }
})
}
handleRowClick = (id) => this.setItemSelectedState(id)
render() {
return (<Table items={people} onRowClick={this.handleRowClick} />)
}
}
这里要注意的是:
>行和表是无状态组件.他们只接受道具并返回jsx.有时它们也被称为表示组件.
> PeopleTable跟踪每个项目的选定状态.这就是为什么它需要状态并且必须是类的原因.
>因为我们不能更改组件props,所以必须在this.state中保留对props.people的引用.
> componentWillReceiveProps确保如果我们的组件收到另一个人员列表,则状态将相应地更新.
> setItemSelectedState成为问题的根源.代替搜索和更新项目(例如在您的this.selectRow(id)方法中),我们使用map创建一个完整的新人员列表并调用setState. setState将触发组件的重新呈现,并且因为我们创建了新的人员列表,所以我们可以在componentWillReceiveProps中使用!== check来检查人员是否已更改.
我希望这个答案对您的问题有所帮助.