在React中进行设计:避免使用redux store将数据从子组件传播到父组件?

时间:2017-02-06 05:58:45

标签: javascript reactjs redux

在以下情况下,我遇到了找到组织数据/ redux商店的最佳方法的问题:

我想显示一个显示用户列表的表。表格上方是一个TableHelper组件,其中包含一个“过滤器”表单(允许我根据某些搜索文本过滤用户列表)。

在下面的代码中,我有一个Table组件,它将数据数组作为props,并为每个元素显示一行。 表助手组件获取数据源(所有用户),根据搜索文本对其进行过滤,并将生成的过滤列表存储在商店中,如store.tableHelper.data

另一方面,该表呈现过滤后的数据(如果存在),如果没有应用过滤器,则只呈现整个数据。

这种方法有许多缺陷,因为表助手组件可以跨应用程序与多个表一起使用,也可以在同一页面上使用。事实上,最好将过滤后的列表完全保留在商店之外。阻止我这样做的唯一障碍是,筛选列表在TableHelper组件内部计算,并且必须以某种方式返回到父容器(其代码在下面),将过滤后的列表提供给表。

在这种情况下是否有可能绕过商店的使用?或者更好的是,考虑到以下约束,为这个问题设计解决方案的更好方法是什么:

  • 将TableHelper保留为自己的组件,以获得更好的可重用性
  • 避免使用每个表的筛选列表污染商店

代码:

@connect((store) => {
  return {
    users: store.user.users,
    filteredData: store.tableHelper.data
  }
})
export default class Users extends React.Component {

  componentDidMount() {
    this.props.dispatch(user.getAllUsers());
  }

  render() {
    const sourceData = _.map(this.props.users, function(user, i) {
      return {
        'name': user.fullName,
        'email' : user.email,
        'key': i
      }
    })

    // tableData shows the filtered data if such data is defined
    // otherwise, tableData is the source data
    let tableData = this.props.filteredData;

    if (!this.props.filteredData) {
      tableData = sourceData;
    }

    return (
      <div>
        <TableHelper data={sourceData}/> 
        <Table tableData={tableData} />
      </div>
    )
  }
}

非常感谢

1 个答案:

答案 0 :(得分:1)

您可以将回调传递给子项作为道具,然后当您的TableHelper组件准备好过滤后的数据时,它可以将信息传递给该回调。您可能希望将其作为父组件内的组件状态,以便在传递过滤后的数据时自动更新,如:

@connect((store) => {
  return {
    users: store.user.users
  }
})
export default class Users extends React.Component {

  componentDidMount() {
    this.props.dispatch(user.getAllUsers());
  }

  // Callback that will be passed to the TableHelper component.
  handleFiltered = (data) => {
    this.setState({
      filteredData: data
    });
  }

  render() {
    const sourceData = _.map(this.props.users, function(user, i) {
      return {
        'name': user.fullName,
        'email' : user.email,
        'key': i
      }
    })

    // tableData shows the filtered data if such data is defined
    // otherwise, tableData is the source data
    tableData = this.state.filtered ? this.state.filtered : sourceData;

    return (
      <div>
        <TableHelper data={sourceData} updateFiltered={this.handleFiltered} /> 
        <Table tableData={tableData} />
      </div>
    )
  }
}

这样,您可以使用回调将数据传回给它的父级,而不是更新TableHelper组件中的Redux存储。