Bra*_*ord 13 javascript reactjs redux
我正在研究一个有很多子组件的组件,其中一些子组件嵌套了五个子组件.我有兴趣使用redux来获得在共同状态原子中具有单一真实来源的优势.
我不理解的是智能/愚蠢的组件推荐,并将提供者置于主要组件之上,并通过道具传递所有内容.如果我这样做,那么我需要将道具一直传递到第五个嵌套项目,这样它就可以进行回调以调度一个动作或查看只有它需要的状态,而不是它的父项.我理解这是用于代码重用,但子组件永远不会在主组件之外使用.这里推荐的解决方案是什么?还在用道具?
注意:该库的作者要求我们在StackOverflow上提问.我之所以提到这一点,是因为SO似乎将"最佳实践"问题标记为过于模糊.
Kye*_*ica 10
虽然发布的答案亚光克莱门斯确实涵盖了这个高水平,但我会尝试在这里更深入.
您可以connect()在任何级别使用.这样做会使组件变得聪明,因为它知道它的props来源.一个愚蠢的组件只有props,它们可以来自任何地方.智能组件与 redux 耦合 ; 一个愚蠢的组成部分不是.
关于这种方法有不同的意见,但它是受支持和有效的.
在哪里绘制这条线完全取决于你,但让我们看一个例子.您有一些聊天客户端,其标准侧边栏组件,消息窗口和用于发送新消息的输入字段.
+---------+--------------------------+
| | |
|Sidebar | Messages window |
| | |
| | |
| | |
| | |
| +--------------------------+
| | New Message Entry **|
| | |
+---------+--------------------------+
Run Code Online (Sandbox Code Playgroud)
所有这些的父级将用于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) => (
<div>
<pre>
{JSON.stringify(data, null, 2)}
</pre>
</div>
)
class SmartChild extends React.Component {
render() {
/* Use the global-like context */
let data = this.context.store.getState();
return (
<div>
<DeepDumbChild data={data}/>
</div>
)
}
}
SmartChild.contextTypes = {
store: React.PropsTypes.object /* required */
}
/* No messy props :) */
var App = () => (<div>
<SmartChild/>
</div>);
render(
<Provider store={createStore(reducers)}>
<App/>
</Provider>,
document.getElementById('app')
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5203 次 |
| 最近记录: |