我是新的反应和减少。 我有一个容器,用一个项目列表和onclick函数初始化一个表组件。 在表组件中,我有每行的复选框。当我单击复选框时,我想选择行(更改其样式并将所选属性添加到其元素模型)。 当我单击复选框时,我调用onclick属性函数,然后通过其id找到列表中的项目,并更改其selected属性。视图不令人耳目一新。 我知道一个组件是一个"愚蠢的"仅绑定道具和渲染的组件。
我做错了什么?
// 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>
})}
谢谢:)
答案 0 :(得分:3)
React组件有props
和state
。
不同之处在于,Component永远不会改变它props
。但它可以改变它的state
。这就是为什么组件将为您提供setState(...)
方法,但不提供setProps(...)
方法。
话虽如此,您在this.props
中更改所选字段的方法基本上是不正确的。 (您的代码中似乎还存在另一个问题,即更改selected
中的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} />)
}
}
这里需要注意的事项是:
Row
和Table
是无状态组件。他们只接受props
并返回jsx。有时它们也被称为表示组件。PeopleTable
会跟踪每个项目的selected
状态。这就是它需要state
并且必须是class
。props
,因此我们必须在props.people
中保留对this.state
的引用。componentWillReceiveProps
确保如果我们的组件收到另一个人员列表,则状态会相应更新。setItemSelectedState
找到问题的根源。我们不会搜索和更新项目(例如您的this.selectRow(id)
方法),而是创建一个包含map
并致电setState
的完整新人列表。 setState
将触发重新呈现该组件,并且由于我们创建了新的人员列表,因此我们可以使用!==
检查componentWillReceiveProps
来检查人员是否已更改。我希望这个答案对你的问题有帮助。