React Redux - 寻找 connect() 的用例
React Redux - Finding a use case for connect()
注意:我使用的是 React Native,但这也适用于 Reactjs。我只按设计使用无状态功能组件。我想尽可能多地学习和使用函数式编程。这是否意味着我永远无法使用 react-redux
中的 connect()
?我应该在我的应用程序设计中添加更多容器组件吗?
这是我的组件示例:
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
- 除非我将高度的存储值传递给它而不是整个商店。
您不必使用 connect(),但您的组件将与 redux 耦合得更紧密。如果你有 Height 容器,你可以从 Height 组件中删除那些 redux 存储代码,并使其可以在其他非 redux 项目中轻松重用。
使用class作为面向对象的模式和一些面向功能的模式混合在一起会产生漂亮的结果。如果你想练习你的函数式编程技能,这是完美的,但遗憾的是,如果你为更严肃的应用程序这样做,你将失去 React 和 redux 的很多好处。状态之类的东西,你的应用程序将很难更新。您的代码将被耦合。并接近修改。在更大的应用程序中,您会发现开发它令人沮丧。不久前我走了完全相同的道路,我很享受将 React 和 Redux 混合在一起的方式。这是我的意见。如果你想使用 connect、component state 以及 react 和 redux 的大部分优点并保持其完整功能,你可以使用 React.createClass()
,这是一个接收对象的函数,其中包含其他函数。就像在 class 构造函数中初始化组件状态一样,您将使用函数 getInitialState
在这种情况下。容器对于获取可重用的组件非常有用。另一个问题是将 redux props 传递给某些组件。使用小应用程序,很容易传递不超过 3 层深度的道具,但在大应用程序中,情况并非如此。想象一下,每次你的 redux 状态改变时,你的整个应用程序都会重新渲染并避免丢失你的数据,你将把这些数据存储在你的 redux 状态中。你的 redux store 会太大并且会包含无用的数据和不应该存在的数据。
总而言之,在全功能模式下做一个小应用程序是完全可以的,但是对于一个更大的应用程序,你会失去很多反应和 redux 的好处,使你的应用程序难以修改和开发。
很高兴看到其他人对此的想法,因为我是新来的。但是我从关于这个问题的其他答案中了解到,connect()
进行了一些性能优化,而且最好不要将整个商店传递给组件,因为 React 高级上下文功能不稳定,而且它在组件中使用 redux store 时将组件耦合到 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)
通过在容器组件上使用连接,您可以保持您的应用正常运行。您的数据流向 children。你的状态是不可变的。
容器组件在连接方面很有用,因为您隔离了对商店的调用,并再次让数据流向 child 组件。这只是构建您的应用程序并减少商店在您的应用程序中调用的点数的好方法。它使开发更易于管理,并减少了造成混乱的机会。
注意:我使用的是 React Native,但这也适用于 Reactjs。我只按设计使用无状态功能组件。我想尽可能多地学习和使用函数式编程。这是否意味着我永远无法使用 react-redux
中的 connect()
?我应该在我的应用程序设计中添加更多容器组件吗?
这是我的组件示例:
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
- 除非我将高度的存储值传递给它而不是整个商店。
您不必使用 connect(),但您的组件将与 redux 耦合得更紧密。如果你有 Height 容器,你可以从 Height 组件中删除那些 redux 存储代码,并使其可以在其他非 redux 项目中轻松重用。
使用class作为面向对象的模式和一些面向功能的模式混合在一起会产生漂亮的结果。如果你想练习你的函数式编程技能,这是完美的,但遗憾的是,如果你为更严肃的应用程序这样做,你将失去 React 和 redux 的很多好处。状态之类的东西,你的应用程序将很难更新。您的代码将被耦合。并接近修改。在更大的应用程序中,您会发现开发它令人沮丧。不久前我走了完全相同的道路,我很享受将 React 和 Redux 混合在一起的方式。这是我的意见。如果你想使用 connect、component state 以及 react 和 redux 的大部分优点并保持其完整功能,你可以使用 React.createClass()
,这是一个接收对象的函数,其中包含其他函数。就像在 class 构造函数中初始化组件状态一样,您将使用函数 getInitialState
在这种情况下。容器对于获取可重用的组件非常有用。另一个问题是将 redux props 传递给某些组件。使用小应用程序,很容易传递不超过 3 层深度的道具,但在大应用程序中,情况并非如此。想象一下,每次你的 redux 状态改变时,你的整个应用程序都会重新渲染并避免丢失你的数据,你将把这些数据存储在你的 redux 状态中。你的 redux store 会太大并且会包含无用的数据和不应该存在的数据。
总而言之,在全功能模式下做一个小应用程序是完全可以的,但是对于一个更大的应用程序,你会失去很多反应和 redux 的好处,使你的应用程序难以修改和开发。
很高兴看到其他人对此的想法,因为我是新来的。但是我从关于这个问题的其他答案中了解到,connect()
进行了一些性能优化,而且最好不要将整个商店传递给组件,因为 React 高级上下文功能不稳定,而且它在组件中使用 redux store 时将组件耦合到 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)
通过在容器组件上使用连接,您可以保持您的应用正常运行。您的数据流向 children。你的状态是不可变的。
容器组件在连接方面很有用,因为您隔离了对商店的调用,并再次让数据流向 child 组件。这只是构建您的应用程序并减少商店在您的应用程序中调用的点数的好方法。它使开发更易于管理,并减少了造成混乱的机会。