react,redux - 使用redux

时间:2017-03-04 15:54:23

标签: javascript reactjs redux

好的,所以我在编写反应时遇到了问题,而且我发现它是一个常见的问题。如果我有多个嵌套组件,在我的情况下我有:

<AppView>
  <Navigation/> // this is a navbar
  <ViewHandler currentTab={props.currentTab}/>
  <Footer/>
</AppView>

然后在<ViewHandler/>我有其他哑的表现组件,它们也有嵌套组件。如果我在<ViewHandler>内的深层嵌套组件中有一个按钮,我想通过更改我所在组件上方的许多父组件来响应该按钮上的onClick,我该怎么办?在我的情况下,我会对在深层嵌套组件中单击的按钮作出反应,然后我想更改<Navigation>上的选定选项卡。我不希望将一堆回调函数作为属性传递下来,因为这感觉非常难以置信。

我学会了redux,因为我读到它解决了这个问题。但对我而言,它还没有。我使用react-redux&#39; <AppView>授予<Provider>访问我的redux商店的权限,我可以通过道具(props.currentTab)访问商店。但是对于嵌套在<AppView>内的所有组件,他们无法访问商店或我的任何动作创建者。如何在深层嵌套的组件中修改我的商店,以便我可以更改父组件而不传递大量的回调函数?或者这只是错误的架构?我认为redux会解决这个问题,但它没有。

是的,我已经连接了我的组件。我不喜欢将store.state信息作为道具传递的想法,因为它对于许多嵌套组件来说非常多余。

2 个答案:

答案 0 :(得分:1)

我不知道为什么你认为必须在组件树中一直发送道具。这是connectmapStateToProps帮助您避免的内容:它们允许您将app状态的某些部分转换为仅针对需要它的组件的道具。

在按钮的onClick处理程序中,创建并发送Redux操作:

// button.js

onClick={() => {
  dispatch({
    payload: 1 // or whatever value
    type: 'SET_SELECTED_TAB'
  });
}}

接下来,让你的reducer函数监视此操作并修改一些Redux app状态:

// reducer.js

if (action.type === 'SET_SELECTED_TAB') {
  return {
    ...currentAppState,
    selectedTab: action.payload
  };
}

最后,在render组件的<Navigation>函数中,您可以根据应用状态位的当前值决定显示哪个标签:

// Navigation.js

render() {
  return (
    <div>
      current tab: {this.props.selectedTab}
    </div>
  );
}

通过connectmapStateToProps访问该状态:

// Navigation.js still

const mapStateToProps = (appState) => {
  return {
    selectedTab: appState.selectedTab
  };
};

export default connect(mapStateToProps)(Navigation);

答案 1 :(得分:0)

Hoc(高阶组件)是一个为子组件提供方法和数据的包装器,通常使用它是一个好主意,但它强制执行一些“规则”。

示例:如果您的HOC处于0级并且您在级别4处有一个深度嵌套的按钮组件,该组件在同一个HOC中调用方法,您应该怎么做?将它传递到所有4个级别?答案是没有办法!

因为这样做会把意大利面带到它上面,每次你点击这个按钮,并假设绑定到它的方法将弄乱状态(内部或商店本身)它将重新渲染所有4个级别,你可以避免通过使用shouldComponentUpdate()但这对于没有用的东西来说太过分了。

因此解决方案是将每个组件与mapStateToPropsmapDispatchToProps连接起来,对吗?

事实上,在广泛使用反应和还原后,你会注意到,对于每个组件,在尺寸,儿童,你应该放入什么以及你不应该做什么方面都有一个最佳点。 / p>

示例:您在表单中有一个控制发送机制的按钮,不需要为按钮创建组件,它会增加复杂性而没有任何好处。只需将其放在表单组件上即可使用。

如果你真的需要在深层嵌套组件和HOC之间调用动作或传递道具,那么在组件级别使用连接模块(对于你的情况是按钮),但不多,因为它会使你的组件更重(加载和显示)。这里有一些提示可以提供帮助:

  • 当你使用mapStateToProps时,你需要尽可能地保持规范,不要返回整个商店,只返回所需的数据,对于mapDispatchToprops来说,只需绑定你将不使用的方法。

  • 在您的情况下,按钮不必知道选择了哪个选项卡,因此mapDispatchToProps就足够了。

  • 避免深层嵌套组件处理某种逻辑,重构结构或为该组件创建A HOC,相反逻辑较少的组件可以深层嵌套

  • 如果您正在编写一个包含大量缩减器和状态的大型应用程序,请考虑使用选择器,以及一些库,例如重新选择。

我知道这不是您所期待的答案,但遵循此指南将为您节省无数小时的重构。

希望有所帮助