问题:
我曾尝试将redux与react-native-router-flux提供的路由结合使用.
简单来说,它不起作用:
> redux状态修改不会出现在视图中,但可以成功记录到控制台
>每次执行操作时,将重新创建包含场景的整个组件树,这会在控制台中产生大量警告,即已创建具有键“xyz”的场景.
我做了什么:
我使用了react-native-router-flux的官方示例应用程序,并添加了一个基于redux的简单反例:
>一个简单的状态:“counter”(可能是一个整数)
>减速器和动作(增量,减量)
下面我将展示一些代码,但也会在github上找到我的example application,请随时查看:https://github.com/itinance/react-native-router-flux.“示例”目录是原始示例应用程序.而“ExampleRedux”是带有redux堆栈和示例reducers(计数器)的示例的副本,我在这里谈论的是什么.
提供者和商店的主要应用程序组件:
import * as reducers from './components/reducers'; const createStoreWithMiddleware = applyMiddleware(thunk)(createStore); const reducer = combineReducers(reducers); const store = createStoreWithMiddleware(reducer); export default class Example extends React.Component { render() { return ( <Provider store={store}> <ExampleContainer/> </Provider> ); } }
我的减速器:
const initialState = { count: 0 }; export default function counter(state = initialState,action = {}) { switch (action.type) { case "INCREMENT": console.log("do increment",state,{ ...state,count: state.count + 1 } ); return { ...state,count: state.count + 1 }; case "DECREMENT": return { ...state,count: state.count - 1 }; default: return state; } }
redux’“connect”的内部应用程序容器:
我将状态和动作传递给场景组件:
<Scene key="launch" component={Launch} title="Launch" initial={true} state={state} {...actions} />
这个ExampleContainer的整个代码:
class ExampleContainer extends React.Component { constructor(props) { super(props); } render() { const { state,actions } = this.props; console.log("Props",this.props,actions); // everything ok here return <Router createReducer={reducerCreate}> <Scene key="modal" component={Modal} > <Scene key="root" hideNavBar={true}> <Scene key="echo" clone component={EchoView} /> <Scene key="register" component={Register} title="Register"/> <Scene key="home" component={Home} title="Replace" type="replace"/> <Scene key="launch" component={Launch} title="Launch" initial={true} state={state} {...actions} /> .... lots of other scenes ... </Scene> </Scene> <Scene key="error" component={Error}/> </Scene> </Router>; } } export default connect(state => ({ state: state.counter }),(dispatch) => ({ actions: bindActionCreators(actions,dispatch) }) )(ExampleContainer);
这是具有简单计数器功能的死亡简易LaunchScreen(以及用于演示路由的示例路由):
class Launch extends React.Component { constructor(props) { super(props); console.log(props); } render(){ const { state,increment,decrement } = this.props; console.log("Props 2: ",decrement); return ( <View {...this.props} style={styles.container}> <Text>Launch page</Text> <Text>{state.count}</Text> <Button onPress={increment}>Increment</Button> <Button onPress={()=>Actions.login({data:"Custom data",title:"Custom title" })}>Go to Login page</Button> <Button onPress={Actions.register}>Go to Register page</Button> <Button onPress={Actions.register2}>Go to Register page without animation</Button> <Button onPress={()=>Actions.error("Error message")}>Popup error</Button> <Button onPress={Actions.tabbar}>Go to TabBar page</Button> <Button onPress={Actions.pop}>back</Button> </View> ); } }
单击Increment-Button时,可以完美地调度操作.在控制台中,可以成功记录新状态.每次点击都会逐一递增.但不是在视图中.
当我省略路由器和场景并仅将启动屏幕激活为单个组件时,一切正常.
题:
如何使这个redux应用程序工作,视图将正确更新其状态?
解决方法
您可能忘记将Launch组件连接到商店.你想要做的是类似于你在ExampleContainer中所做的,即
export default connect(state => ({ state: state.counter }),dispatch) }) )(Launch);
然后正确的值将显示在您的日志中