【问题标题】:How to properly use redux with react-native navigation如何正确使用带有 react-native 导航的 redux
【发布时间】:2025-11-06 10:20:01
【问题描述】:

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

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

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

所以我的问题是:您如何使用 redux 路由您的 react 原生应用程序?你使用其他库吗?是否有任何示例或文档资源可以用来修复我的代码?

认为它具有典型的 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>
    )
  }
}

【问题讨论】:

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


【解决方案1】:

根据我的痛苦经历,如果将 Provider 包裹在 Provider 下并收听来自 redux 的更新,则无法防止 Router 重新渲染,这是设计的本质。

如何防止这种情况的关键是:Router 应该只渲染一次 意思是:

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

另外,您可以通过connect() Routerredux 获得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>
        );
    }
}

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

记分:

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

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

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

感谢@jsdario 在此提及,希望对您有所帮助

【讨论】:

    【解决方案2】:

    我只使用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);
    

    【讨论】:

    • 您能否详细说明一下路由方面?此外,您似乎正在将组件连接到一个一个状态,而不是使用商店。我错了吗?
    • 路由?你在这里是什么意思?是的,我正在连接组件而不是使用商店。
    • 通过路由我的意思是,就像在问题正文中一样,我无法将 redux 与 react-native-router-flux 连接起来,所以我在寻求替代方案。我仍然想要一个场景 API。
    【解决方案3】:

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

    您可以在此link 上找到更多相关信息。

    【讨论】:

    • 恐怕我们还不能支持生产应用程序的实验性功能。
    • 是的,我认为这是每个人自己决定的。我的理由是它包含在 react-native 中,因此它将被开发并可能成为一个标准(而且,它实际上是被合并的 react-native-router-flux 类库之一)。也许有人会按照我的想法进行调查和思考。
    最近更新 更多