Reactjs访问另一个组件的状态

时间:2018-11-08 13:33:00

标签: reactjs redux

基本上,我有一个名为Timeperiod的组件,它是一个下拉菜单,用户可以在其中选择诸如“今天”,“昨天”,“上周”等值。

我想在其他许多组件中重复使用<Timeperiod>组件,问题是如果我在另一个组件中调用它,我将无法访问他们选择的值。

我知道一种替代方法是在Timeperiod内部调用我的其他组件,并根据Timeperiod状态传递它们的属性,但这不是意味着我需要创建多个类似Timeperiod的类吗?

redux或某种方法可以解决这些情况吗?

这是我的密码和框:https://codesandbox.io/s/ypyoq8zoz

现在,我只有App.js调用Timeperiod,但是我还将有更多的类调用它。我希望能够在使Timeperiod类可重用的同时访问App.js中选择的日期。

3 个答案:

答案 0 :(得分:3)

要确定是否需要Redux以及需要多少Redux,必须仔细考虑正在开发的整个应用程序。 Redux添加了一些样板,对于您可能会获得的好处来说可能太多了。

但是,您无需Redux就可以解决您的问题。

没有Redux

React下的关键思想之一是“提升状态”。这意味着,如果多个组件需要访问同一数据,则绝对应该将该数据的存储移动到作为所有这些组件的共同祖先的组件中(请参阅https://reactjs.org/docs/lifting-state-up.html)。 在您的情况下,Timeperiod不负责保存所选日期,而应负责App(实际上,是需要访问选定时间段的所有组件的最接近的共同祖先)。时间段应通过属性从应用中获取所选日期,并在用户使用事件(同样是包含函数的道具)更改所选日期时通知App。

class App {
  constructor(props) {
    super(props);
    this.state = {
      start: new Date(), // initial value
      end: new Date(),   // initial value
    }
  }
  render() {
    return (
      <Timeperiod 
         start={this.state.start} 
         end={this.state.end}
         onStartChange={newValue => this.setState({ start: newValue })}
         onEndChange={newValue => this.setState({ end: newValue })}
      />
    );
  }
}

使用Redux

Redux允许您保留全局状态,并在称为“容器”的特殊组件中访问它。您可以在文档树的任何位置放置所需的容器数量。这看起来不错,但有几个缺点:

  • 太多的容器组件会降低性能
  • 如果您不十分小心,则完全可以访问树的任何点的整个状态可能会造成问题。组件可能会修改某些不应允许访问的数据,依此类推。
  • Redux引入了一些样板,如果应用程序简单,则可能会太多 对于任何更新,您都必须定义一些能够处理它的动作,创建一个化简器以从先前状态和动作中产生下一个状态,并将所有这些片段连接在一起

结论 Redux的好坏取决于您的应用程序,但是如果您的组件层次结构不太深并且您的应用程序不太复杂,那么采用香草方式可能会更好

答案 1 :(得分:1)

使用redux可以做的是在自己的状态下拥有timePeriod子状态,该子状态由专用的reducer处理,该子状态存储用户的选择。

然后,您的每个TimePeriod组件都将使用类似的方式钩住该状态

const ConnectedTimePeriod = connect(
  state => state.timePeriod,
  {
    onTimePeriodChoose (timePeriod) {
      return {
        type: "CHOOSE_TIME_PERIOD",
        timePeriod
      }
    }
  }
)(TimePeriod);

这使您的组件具有全局共享状态,并提供了作为更新时间段的道具的功能。

ConnectedTimePeriod然后可以在任何地方使用,并将共享全局状态。

我建议您看看react-redux文档以获取示例和详细信息。

答案 2 :(得分:1)

因此,请继续我们的评论。这是您的处理方法:

Edit Date Picker

Timeperiod组件需要一个getDate参数的title函数。渲染Timerperiod组件时,每次都有单独的状态和道具。

  

查看我如何渲染多个(在app.js中),以显示实际效果。