需要有关在基于反应的数据表中封装逻辑的指导

时间:2018-05-02 21:16:58

标签: reactjs datatable datagrid redux react-redux

我尝试使用react-virtualized创建可重复使用的反应数据表组件,并需要有关状态管理的指导。

我实现了服务器端过滤/排序/无限滚动,并使用本地组件状态来存储表上下文(过滤器,当前页面,数据行等)。

简化示例:

  class DataTableWithFilter
      render() {
        return ( 
              <React.Fragment>
              <DataTableFilterBar
                   value={this.state.filter}
                   onFilterChange={this._handleFilterChange}
                   onSort={this._handleSort}
                   onScroll={this._handleScroll}
               />
              <VirtualizedDataTable
                  records={this.state.records}
              />                      
              </React.Fragment>
        )
      }
      _handleFilterChange() {
         // build up url from state (path, filter, sort index, page index, etc)
         // fetch new data
         // put new data into state
      }
      _handleSort() {...}
      _handleScroll() {...}
      etc
  }

不惜一切代价,我试图阻止复制表中使用的任何逻辑,并将其完全封装在表组件中。该表将使用数十个时间,因此我希望表知道如何加载自己的数据和处理排序/过滤/滚动,并在不同的上下文中使用。

但是这变得越来越复杂,因为表的不同用法要求父组件和兄弟组件能够告诉表重新加载它的数据。 例如,添加新记录&#39;弹出模态的按钮,然后在将新记录发布到服务器后需要表重新加载。或者删除记录&#39;将删除发布到服务器后需要重新加载数据表的按钮。

我看到了几个选项:

1)创建一个包含所有状态和过滤/排序/滚动/模态/按钮行为的单片EditableDataTableWithFilter组件,并可选择呈现某些子组件,如过滤栏或模态。缺点是将所有内容都放在一个组件中,并且在将组件用作没有过滤或上下文相关按钮/模式的简单数据表时,会有很多不必要的行为。这看起来真的很糟糕。

2)创建一个EditableDataTable组件,该组件呈现子DataTableWithFilter组件,并添加显示和提交模态数据所需的逻辑。我假设这样做会再次要求将表数据移动到EditableDataTable本地状态并作为prop传递给DataTableWithFilter,以便在数据更改时表重新加载。或者,我需要找到一些方法来告诉&#34;子DataTableWithFilter重新加载其数据。后者,使用refs或类似的看起来像一个糟糕的方法,再次打破封装。而且我不确定如何使用属性作为&#34;重新加载触发器&#34;任

3)使用像redux这样的集中式状态提供程序。我还没有将redux引入项目,但我想知道这是否是最好的解决方案。

1 个答案:

答案 0 :(得分:0)

在下面找到组件结构(它只是一个伪代码)。 ok_cb,cancel_cb是传递给ModalThatNeedsToReloadTable组件的回调,并从ModalThatNeedsToReloadTable调用该组件。回调将使用setState()方法在状态中设置所需数据,这将重新呈现整个Container组件。希望这会有所帮助。

<Container>
    // in this component you can set the data shared between all
    // the components within the container in the components 'state'

    cancel_cb() {
        // this cb will call the set state
        // method which will re-render the component
    }

    ok_cb() {
        // this cb will call the set state
        // method which will re-render the component
    }


    render()

        if(this.props.showModal)
            <ModalThatNeedsToReloadTable show={this.state.showModal}
                onCancelClick={this.cancel_cb}
                onOKClick={this.ok_cb}/>

        <SmartTableComponent> <DumbTableComponent> </SmartTableComponent>

</Container>