如何在反应原生导航中正确使用redux

时间:2016-08-23 09:59:26

标签: javascript reactjs react-native redux react-redux

我一直在尝试使用react-native-router-flux进行设置并按照步骤操作。然后尝试按照示例进行操作,并记录大量信息以尝试对其进行反向工程。 然而,即使遵循我能找到的所有信息,我最终得到了一些奇怪的状态结构:

enter image description here

scene是包含路由器状态的对象。但是,初始状态在scene内复制(因此它再次包含devicesrooms个对象。

如果我更改普通状态设备或路由,则会引发错误:Key <name of the key> has already been defined(其他人报告相同的问题here)。

所以我的问题是:你如何使用redux路由你的本机应用程序?你使用其他图书馆吗?我可以使用任何示例或文档资源来修复我的代码吗?

认为它具有典型的redux结构。为了示例,这是它在app/index.js上的外观:

import React, { Component } from 'react'
import { Router, Scene } from 'react-native-router-flux'
import { createStore, applyMiddleware, compose } from 'redux'
import { Provider, connect } from 'react-redux'
import logger from 'redux-logger'

import reducers from './reducers'
import Home from './components/home'
import Device from './components/devices'
import Login from './components/login'

const middleware = [logger()]
const store = compose(
  applyMiddleware(...middleware)
)(createStore)(reducers)

const RouterWithRedux = connect(reducers)(Router)

export default class AppContainer extends Component {
  render () {
    return (
      <Provider store={store}>
        <RouterWithRedux>
          <Scene key='login' component={Login} title='Login' />
            <Scene key='root' initial={true}>
            <Scene key='home' component={Home} title='Home' />
            <Scene key='device' component={Device} title='Device' />
          </Scene>
        </RouterWithRedux>
      </Provider>
    )
  }
}

3 个答案:

答案 0 :(得分:2)

根据我的痛苦经历,如果你将Router包裹在Provider下并从redux收听更新,则无法阻止Router重新呈现,这是设计的本质。

如何防止这种情况的一点是: Router应该渲染一次 这意味着:

如果您根本没有连接到redux,它可以正常工作,因为来自redux的任何更新都不会触发connect()

另外,您可以Router reduxdispatch()获取import { Router, Scene, Actions, } from 'react-native-router-flux'; // --- child component can connect and listen to props they want. const myConnectedMainConponent = connect()(myMainConponent); const myConnectedLoginConponent = connect()(myLoginConponent); // --- Create it via Actions.create(), or it will be re-created for each render of your Router const scenes = Actions.create( <Scene key="root"> <Scene key="login" component={myLoginConponent} /> <Scene key="main" component={myMainConponent} /> </Scene> ); // --- Create connected Router if you want dispatch() method. // --- Or you can just use vanilla Router const myConnectedRouter = connect()(Router); // --- your exported main router export default class MyExportedRouter extends React.Component { constructor(props) { super(props); }; render() { return ( <Provider store={store}> <myConnectedRouter scenes={scenes} /> </Provider> ); } } 方法道具,但不能听其他道具。

因此,架构将是:

Router

P.S。我在这里直接输入上面的代码,请注意语法错误:)

采取的点:

  1. User应该只渲染一次(连接到仅获取调度方法或根本不连接)
  2. 通过Actions.create()创建场景并将其传递给路由器
  3. 将您的应用主逻辑移动到路由器
  4. 的子节点之一

    =====================

    这最初是在https://github.com/aksonov/react-native-router-flux/issues/376#issuecomment-241965769

    上回复的

    感谢@jsdario在这里提一下,希望这有帮助

答案 1 :(得分:1)

我只使用reduxreact-redux。 使用createStore创建带有一些中间件的商店(在执行combineReducers之后):

const store = createStore(
  rootReducer,
  compose(applyMiddleware(thunk, promiseMiddleware())),
);

注册应用:

AppRegistry.registerComponent('app', () => () => (
  <Provider store={store}>
    <MainComponent />
  </Provider>
));

在组件中使用状态:

const mapStateToProps = (state) => ({
  isLoading: state.core.isLoading,
});

使用connect

将组件连接到州
export default connect(mapStateToProps)(HomeScene);

答案 2 :(得分:0)

您现在也可以直接从react-native使用NavigationExperimental

您可以在此link上找到有关它的更多信息。