如何在本机导航中正确使用redux

jsd*_*rio 5 javascript reactjs react-native redux react-redux

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

在此处输入图片说明

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

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

所以我的问题是:如何通过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>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

小智 2

根据我的痛苦经历,如果您将其包装在 a 下并监听来自的更新,则无法阻止Router重新渲染,这是设计的本质。Providerredux

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

如果你根本没有连接到 redux,它可以正常工作,因为你Router不会被 redux 的任何更新触发。

另外,您可以connect() Router获取redux方法dispatch()道具,但不能收听另一个道具。

因此,架构将是:

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>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

ps 我直接在这里输入上面的代码,注意语法错误:)

采取的要点:

  1. Router应该渲染一次并且仅渲染一次(仅连接到获取调度方法或根本不连接)
  2. 通过 Actions.create() 预先创建场景并将其传递到 Router
  3. 将您的应用程序主逻辑移至 Router 的子级之一

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

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

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