用Redux和react-redux测试React Native,我发现如果状态不是通过 Container 传递的,Redux 的状态树的内容不会反映在显示中。
为了测试这个我使用
- 反应原生 0.19.0
- 反应还原 4.1.2
- 还原 3.1.7
正如@alinzin 在https://github.com/alinz/example-react-native-redux中解释的那样,其中包含设置此项目的所有技巧。还有其他好的解决方案吗?
下一个例子展示了一个简单的字符串作为 Redux 存储中的状态,以及一个简单的操作来扩大字符串。
这是在状态中作为单个字符串的 reduce 和数据。
//Reducer
const reducer = (state = { data: '[][][]' }, action = {}) => {
switch (action.type) {
case ENLARGE:
return Object.assign({}, state, {
data: state.data+'[]'
})
default:
return state
}
}
注册的App就是这样,没什么新意。初始路由启动 App1Component 的容器。这是良好的绑定状态和组件的方式(我相信)
export default class App extends Component {
render () {
return (
<Provider store={store}>
<Navigator style={{flex: 1}}
initialRoute={{
component: Container,
}}
renderScene={ (route, navigator) => {
const Component = route.component;
return (
<View style={{flex: 1, marginTop:40}}>
<Component navigator={navigator} route={route} {...route.passProps} />
</View>
);
}}
/>
</Provider>
)
}
}
组件 App1Component 和 App2Componenet 的主要内容是一个简单的组件,只显示字符串,并显示一个“按钮”来调度放大操作。
class MainContent extends Component{
render() {
return (
<View>
<Text>{this.props.data}-{this.props.data.length}</Text>
<TouchableOpacity onPress={()=>{this.props.enlarge()}} >
<Text>Click to Enlarge me!</Text>
</TouchableOpacity>
<Text> </Text>
</View>
)
}
}
组件 App1 和 App2 之间没有区别。只是 App1Component 通过容器调用(并绑定状态和操作),并且通过使用 Navigator 推送所有相同的道具(在 App1Component 中相同)调用 App2Component(从 App1Component)
这是带有按钮的 App1Component,用于将下一个场景推送到 App2Component 并在通过 Container 绑定之前传递相同的道具。
class App1Component extends Component {
render() {
return (
<View>
<MainContent {...this.props}/>
<TouchableOpacity onPress={()=>{
this.props.navigator.push({
name: 'App2',
component: App2Component,
passProps: {...this.props}
})
}}>
<Text>Click to Forward to App2Component {'\n'}passing props through Navigator passProps</Text>
</TouchableOpacity>
</View>
)
}
}
如果您在此处按“放大”,则字符串被放大,您可以看到屏幕上反映的动作。您还可以在 chrome 中看到 redux 记录器的跟踪。
这里是 App1Component 的包装容器
const Container = connect(
(state) => ({
data: state.data
}),
(dispatch) => ({
enlarge: () => dispatch(enlarge())
})
)(App1Component)
这里是组件 2,带有后退按钮。如果您在此处按“放大”,则字符串会被放大,确保您可以在 chrome 上看到痕迹,但是……该动作不会反映在屏幕上。
class App2Component extends Component {
render() {
return (
<View>
<MainContent {...this.props}/>
<TouchableOpacity onPress={()=>{this.props.navigator.pop()}} >
<Text>Back to App1Component{'\n'}to see the change!</Text>
</TouchableOpacity>
</View>
)
}
}
按 Back 后,您可以在屏幕上看到 App1Component 的字符串已修改。
如您所见,我误解了一些基本的东西,但不是。
我必须用容器装饰所有主要组件(页面/场景)吗?为什么在 Navigator 中通过 passPros 传递道具(之前由容器绑定)是错误的?动作被正确分派,但不会反映在屏幕上。
欢迎任何帮助。谢谢