【问题标题】:Change parent state without rerendering parent, but rerender a child在不重新渲染父级的情况下更改父级状态,但重新渲染一个子级
【发布时间】:2016-08-05 03:46:48
【问题描述】:

我对反应还很陌生,我想知道是否可以执行以下操作。

我有一个状态,它仅用于在两个不同的子组件之间传输信息。第一个孩子是一个表(BootstrapTable)。当我单击该行时,将调用一个 onClick 函数。此函数将父状态设置为所有当前单击的行的数组。然后,此信息将传递给第二个孩子,这将允许我将行提交到后端服务器进行处理。目前,父级重新渲染会删除表中的复选标记。而且,因为我使用的是节点模块,所以我无法控制表格行的行为方式(在使用自定义创建的表格之前,我能够在收到新道具后立即设置复选框状态,因此我可以手动将其更改回原来的状态曾经是)。

我能看到的唯一解决方案是将更改后的状态传递给孩子而不重新渲染。这是可能的还是我设计错了?如果是这样,它应该是什么?

getInitialState : function () {
    return (
        {
            tableData : [],
            selectedRows : []
        }
    );
}

onRowSelect : function () {
    this.setState({selectedRows : this.refs.table.state.selectedRowKeys}, 
        function () {
            console.log('selectedRows are ', this.state.selectedRows);
        }
    );
},
render : function () {
    if (this.state.tableData.length === 0) {
        return (<div>Loading...</div>);
    } else {
        return (
        <div className='full-table'>
            <div className='react-table'>
                <BootstrapTable 
                    ref='table'
                    data={ this.state.tableData }
                    selectRow={ this.getSelectRowProps() }
                    options={ this.getOptions() }
                    insertRow
                    deleteRow
                    search
                    columnFilter
                    hover
                    pagination>
                    <TableHeaderColumn dataField='key' dataAlign='right' hidden={true} isKey={true}>
                        Key
                    </TableHeaderColumn>
                    <TableHeaderColumn dataField='in_progress_text' dataAlign='right'>
                        In-Progress
                    </TableHeaderColumn>
                    <TableHeaderColumn dataField='payment_id' dataAlign='right'>
                        Id
                    </TableHeaderColumn>
                    <TableHeaderColumn dataField='product_code' dataAlign='center'>
                        Type
                    </TableHeaderColumn>
                    <TableHeaderColumn dataField='status_description' dataAlign='center'>
                        State
                    </TableHeaderColumn>
                    <TableHeaderColumn dataField='payment_amount' dataAlign='center'>
                        Amount
                    </TableHeaderColumn>
                    <TableHeaderColumn dataField='payment_currency' dataAlign='center'>
                        Currency
                    </TableHeaderColumn>
                    <TableHeaderColumn dataField='process_state' dataAlign='center'>
                        Status
                    </TableHeaderColumn>
                    <TableHeaderColumn dataField='process_message' dataAlign='left'>
                        Message
                    </TableHeaderColumn>
                </BootstrapTable>
            </div>
            <div className='submit-buttons'>
                    <SubmitButtonContainer selectedRows={this.state.selectedRows} />
            </div>
        </div>
    );
    }
}

【问题讨论】:

  • 添加一些代码示例。
  • 已添加代码示例。
  • 如果您可以访问某种通量实现,那么您可以使用它们在组件之间进行通信。

标签: reactjs


【解决方案1】:

渲染应该是幂等的;即您应该能够重新渲染父级(甚至多次)而不影响任何内容。这听起来像是在 React 中管理某些状态而在 React 之外管理某些状态的问题。当 React 可以拥有和管理影响其呈现的事物的所有状态时,它会做得更好。

【讨论】:

  • 您能否详细说明您所说的“某些状态在 React 中管理,而某些状态在 React 之外管理”的意思?我正在使用一个名为 react-bootstrap-table 的表。您是说节点模块可能没有正确管理子状态?
  • 哦,好吧,所以你正在用 React 做所有事情。我认为您可能正在尝试与某些第三方非反应库进行交互。无论哪种情况,我的第一个陈述都是如此,渲染不应该改变状态。
  • 我不确定你是否真的在这里使用了 onRowSelect 函数,但如果你是父母,你会进入孩子的状态,这不是你应该在 React 中做事的方式。 React 使用“单向数据流”,其中数据总是从父级流向子级。这种状态很可能应该只存在于父级中,并通过道具传递给子级。
  • 进一步扩展,组件永远不应该直接知道另一个组件的状态。相反,组件将通过道具共享其状态的相关部分,仅对子级。如果一个孩子需要改变那个状态,那么父母将提供一个函数来再次使用道具来做到这一点。该函数存在于父级中,因此父级是唯一可以实际更改状态的地方,但是该函数可以在道具中传递给子级,这允许子级在父级中修改状态。
  • 我进入子状态的原因是提取已单击了哪些行的复选框。根据 react-bootstrap-table API,这似乎是正确的方法。除此之外,我不确定如何访问是否已检查行的信息。
猜你喜欢
  • 2020-06-28
  • 2021-10-29
  • 2018-12-28
  • 1970-01-01
  • 2017-03-06
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 2022-09-28
相关资源
最近更新 更多