我正在研究一个有很多子组件的组件,其中一些子组件嵌套了五个子组件.我有兴趣使用redux来获得在共同状态原子中具有单一真实来源的优势.
我不理解的是智能/愚蠢的组件推荐,并将提供者置于主要组件之上,并通过道具传递所有内容.如果我这样做,那么我需要将道具一直传递到第五个嵌套项目,这样它就可以进行回调以调度一个动作或查看只有它需要的状态,而不是它的父项.我理解这是用于代码重用,但子组件永远不会在主组件之外使用.这里推荐的解决方案是什么?还在用道具?
注意:该库的作者要求我们在StackOverflow上提问.我之所以提到这一点,是因为SO似乎将"最佳实践"问题标记为过于模糊.
虽然发布的答案亚光克莱门斯确实涵盖了这个高水平,但我会尝试在这里更深入.
您可以connect()
在任何级别使用.这样做会使组件变得聪明,因为它知道它的props
来源.一个愚蠢的组件只有props
,它们可以来自任何地方.智能组件与 redux 耦合 ; 一个愚蠢的组成部分不是.
关于这种方法有不同的意见,但它是受支持和有效的.
在哪里绘制这条线完全取决于你,但让我们看一个例子.您有一些聊天客户端,其标准侧边栏组件,消息窗口和用于发送新消息的输入字段.
+---------+--------------------------+ | | | |Sidebar | Messages window | | | | | | | | | | | | | | +--------------------------+ | | New Message Entry **| | | | +---------+--------------------------+
所有这些的父级将用于connect()
从redux获取数据并通过props将其提供给这些组件.现在想象那两个星号除了new message entry
打开一个设置面板(忽略愚蠢的位置,这是一个例子).new message entry
通过这些道具真的有意义吗?不,它没有.
为了解决这个问题,你可以创建一个特殊的"容器",让我们把它叫做SettingsContainer
是用来connect()
获取其道具和它所作的只是将它们传递下来SettingsPopup
.SettingsPopup
不会知道redux,并且仍然可以正常测试/样式化/重用,而新的消息条目只需要知道SettingsContainer
,而不是任何依赖.
这种方法可以很好地扩展,但它有两个惩罚.首先,智能"包装"组件SettingsContainer
必须由其他愚蠢的组件消耗.这使新消息条目组件的测试变得复杂.其次,顶级组件不再公开数据依赖关系的整个图形,这使得在不深入研究组件层次结构的情况下更难以推理.
这些权衡可能是值得的,但你应该知道它们.
您可以使用'react-redux'的组件提供程序,使用上下文的较新React功能.使用Provider将抽象出一些上下文的实现细节,使你的标记非常富有表现力.
您基本上设置了一个迷你全局属性,所有子组件,哑或智能可以引用:
import React from 'react'; import {render} from 'react-dom'; import {createStore} from 'redux'; import {Provider} from 'react-redux'; //Special Redux component to help import {reducers} from './reducers.js'; var DeepDumbChild = (props, context) => () class SmartChild extends React.Component { render() { /* Use the global-like context */ let data = this.context.store.getState(); return ({JSON.stringify(data, null, 2)}) } } SmartChild.contextTypes = { store: React.PropsTypes.object /* required */ } /* No messy props :) */ var App = () => ( ); render(, document.getElementById('app') );