【问题标题】:React Redux table update rowReact Redux 表更新行
【发布时间】:2017-08-11 16:31:31
【问题描述】:

我是 react 和 redux 的新手。 我有一个容器,它使用项目列表和 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 如何知道你已经更改了 selected 属性?如果它不知道它不会重新渲染您的组件。您有两个选择:1)将您的people 数组存储在People 组件的this.state 中,并使用this.setState() 方法更改selected 属性。 2) 如果您使用的是 redux,请将 people 数组存储在 redux 存储中并通过 redux 操作更改 selected 属性。

标签: javascript reactjs redux


【解决方案1】:

一个 React 组件有 propsstate

不同之处在于,组件永远不会更改它props。但它可以更改为state。这就是为什么组件会为您提供setState(...) 方法,但没有setProps(...) 方法。

话虽如此,您更改this.props 中选定字段的方法基本上是不正确的。 (您的代码中似乎还有另一个问题,您更改了this.props.leads 中的selected 字段,但将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。有时它们也被称为presentational组件。
  2. PeopleTable 跟踪每个项目的 selected 状态。这就是为什么它需要state 并且必须是class
  3. 因为我们不能更改组件props,所以我们必须在this.state 中保留对props.people 的引用。
  4. componentWillReceiveProps 确保如果我们的组件收到另一个人员列表,状态会相应更新。
  5. setItemSelectedState 找到问题的根源。我们不是搜索和更新项目(如在您的this.selectRow(id) 方法中),而是使用map 创建一个完整的新人员列表并调用setStatesetState 将触发组件的重新渲染,因为我们创建了一个新的人员列表,我们可以使用 !== 签入 componentWillReceiveProps 来检查人员是否已更改。

我希望这个答案对您的问题有所帮助。

【讨论】:

    猜你喜欢
    • 2016-08-10
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 2021-06-18
    • 2018-08-30
    相关资源
    最近更新 更多