注意:我使用的是React Native,但这也适用于Reactjs。我只在设计中使用无状态功能组件。我想尽可能多地学习和使用函数式编程。这实际上是否意味着我永远不能使用connect()
中的react-redux
?我应该在我的应用设计中添加更多容器组件吗?
以下是我的组件示例:
export const Height = (props, { store }) => {
const state = store.getState()
return (
<View style={formStyles.container}>
<DimenInput
value={state.get('height').get('height1').toString()}
onChangeText={text => store.dispatch(updateHeight(text, 1))}
/>
<Text style={formStyles.text}>{'&'}</Text>
<DimenInput
value={state.get('height').get('height2').toString()}
onChangeText={text => store.dispatch(updateHeight(text, 2))}
/>
</View>
)
}
Height.contextTypes = {
store: React.PropTypes.object
}
我还想学习我将在行业中看到的所有常见的redux和react技术,因此我想学习mapStateToProps()
和connect()
。我开始尝试为上面的组件创建这些函数:
const mapStateToProps = (state) => {
return state.get('height').get('height1').toString()
}
const mapDispatchToProps = (dispatch) => {
return {
onHeightChanged: (text) => {dispatch(updateHeight(text, 1))}
}
}
在意识到我无法在这个无状态组件上使用这些功能之前。我必须在一个基本上容纳这个组件的容器组件上使用它们,但我不是真的有一个,这个组件的容器是:
export const Volcalc = () => {
return (
<View style={styles.container}>
<Text style={styles.text}>HEIGHT</Text>
<Height/>
<Text style={styles.text}>WIDTH</Text>
<Width/>
</View>
)
}
然后容器就是:
const App = () => {
return (
<Provider store={store}>
<Volcalc/>
</Provider>
)
}
我制作的应用程序是单一形式 - 所以它很小。在这个阶段,我看不到任何我必须使用容器组件的情况。在一个更大的应用程序中,我将被迫使用容器组件,然后我将有机会使用connect()
?哪种技术最好只使用无状态,并使用用connect()
创建的容器,如果它可以以任何方式完成?
修改:this egghead lesson在他们拥有无状态组件AddTodo
之间做了一些事情,该组件使用商店中的dispatch
并在其上调用connect()
。可能是适合我Height
用例的场景,虽然我需要继续将其传递给完整商店,因为它使用store.get
和store.dispatch
- 除非我传递高度的商店值而不是完整的商店。
答案 0 :(得分:2)
通过在容器组件上使用connect,您可以保持应用程序正常运行。您的数据会流向儿童。你的国家是不变的。
容器组件在连接方面非常有用,因为您将对商店的调用隔离开来,并且再次让数据流向子组件。这是构建应用程序的好方法,可以减少应用程序中调用商店的点数。它使开发更容易管理,并减少创建混乱的机会。
答案 1 :(得分:1)
您不必使用connect(),但您的组件将与redux紧密结合。如果你有高度容器,你可以从高度组件中删除那些redux商店代码,并使其可以在其他非redux项目上轻松重复使用。
答案 2 :(得分:1)
使用class作为面向对象的模式和一些功能导向模式混合在一起产生了美丽的结果。如果你想练习你的函数式编程技巧,这是完美的,但遗憾的是,如果你这样做是为了更严肃的应用程序,你将从react和redux中获得很多好处。像州,你的应用程序将很难更新。你的代码将被耦合。并接近修改。在更大的应用程序中,您会发现开发它令人沮丧。我不久前采取了完全相同的路径,我很享受反应和减少方式混合两者。这是我的意见。如果你想使用连接,组件状态以及react和redux的大多数优点并使其保持完全正常运行,你可以使用React.createClass()
,这是一个接收带有其他功能的对象的函数。与在类构造函数中初始化组件状态不同,在这种情况下,您将使用函数getInitialState
。容器对于获取可重用组件非常有用。另一个问题是将redux道具传递给某些组件。使用一个小应用程序,很容易通过不超过3级的道具,但在一个大的应用程序,它不是。想象一下,每次你的redux状态改变,你的整个应用程序重新渲染并避免丢失数据,你将把这些数据存储在你的redux状态。您的redux存储将太大,并将包含不应存在的无用数据和数据。
总而言之,在完整功能模式下完成一个小应用程序是完全没问题的,但是对于更大的应用程序,您将失去很多反应和减少的好处,使您的应用程序难以修改和开发。
答案 3 :(得分:1)
很高兴看到其他人对此有这样的看法,因为我正在进入新的领域。但是我从这个问题的其他答案中得知,connect()
有一些性能优化,并且最好不要将整个商店传递给组件,因为反应高级上下文功能不稳定而且它也是在组件中使用redux存储时,将组件耦合到redux。
我已经完成了一些教程,并意识到我可以在我的无状态组件上使用connect()
,从而获得上述好处。
代码:
const mapStateToProps = (state) => {
return {
height1: state.get('height').get('height1').toString(),
height2: state.get('height').get('height2').toString()
}
}
const mapDispatchToProps = (dispatch) => {
return {
updateHeight: (text, number) => {
dispatch(updateHeight(text, number))
}
}
}
let Height = (props) => {
return (
<View style={formStyles.container}>
<DimenInput
value={props.height1}
onChangeText={text => props.updateHeight(text, 1)}
/>
<Text style={formStyles.text}>{'&'}</Text>
<DimenInput
value={props.height2}
onChangeText={text => props.updateHeight(text, 2)}
/>
</View>
)
}
Height.propTypes = {
height1: React.PropTypes.string.isRequired,
height2: React.PropTypes.string.isRequired,
updateHeight: React.PropTypes.func.isRequired
}
Height = connect(
mapStateToProps,
mapDispatchToProps
)(Height)