React Redux表更新行

时间:2017-03-20 11:52:11

标签: javascript reactjs redux

我是新的反应和减少。 我有一个容器,用一个项目列表和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>
})}

谢谢:)

1 个答案:

答案 0 :(得分:3)

React组件有propsstate

不同之处在于,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} />)
    }
}

这里需要注意的事项是:

  1. RowTable无状态组件。他们只接受props并返回jsx。有时它们也被称为表示组件。
  2. PeopleTable会跟踪每个项目的selected状态。这就是它需要state并且必须是class
  3. 的原因
  4. 由于我们无法更改组件props,因此我们必须在props.people中保留对this.state的引用。
  5. componentWillReceiveProps确保如果我们的组件收到另一个人员列表,则状态会相应更新。
  6. setItemSelectedState找到问题的根源。我们不会搜索和更新项目(例如您的this.selectRow(id)方法),而是创建一个包含map并致电setState的完整新人列表。 setState将触发重新呈现该组件,并且由于我们创建了新的人员列表,因此我们可以使用!==检查componentWillReceiveProps来检查人员是否已更改。
  7. 我希望这个答案对你的问题有帮助。