ios - 将 react-native-router-flux 与 redux 一起使用,如何更新 View 组件中的状态?

标签 ios routing react-native redux react-redux

问题:

我尝试将 redux 与 react-native-router-flux 提供的路由结合使用.

简单来说,它不起作用:

  • redux 状态修改不会出现在 View 中,但可以成功记录到控制台
  • 每次执行操作时,都会重新创建包含场景的整个组件树,这会导致控制台中出现大量警告,表明已经创建了具有键“xyz”的场景。

我做了什么:

我使用了react-native-router-flux官方的示例应用,并添加了一个简单的基于redux的反例:

  • 一个简单的状态:“计数器”(可能是一个整数)
  • reducer 和 action(递增、递减)

下面我将展示一些代码,但也可以找到我的 example application在github上,请随时查看:https://github.com/itinance/react-native-router-flux . “示例” 目录是原始示例应用程序。 “ExampleRedux” 是带有 redux 堆栈和示例 reducer(计数器)的示例的副本,我在这里谈论的是什么。

主应用程序组件与提供者和商店:

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>
        );
    }
}

我的 reducer :

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 的“连接”的内部应用程序容器:

我将状态和 Action 传递给场景组件:

<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, state, 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: ", this.props, state, increment, 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>
        );
    }
}

当点击增量按钮时, Action 被完美地调度。在控制台中,可以成功记录新状态。每次单击它都会一个一个递增。但不在 View 中。

当我省略路由器和场景并仅将启动屏幕作为单个组件激活时,一切正常。

问题:

如何让这个 redux 应用程序工作, View 将正确更新它们的状态?

为了完整起见,完整代码可以在github上找到.

最佳答案

您可能忘记将 Launch 组件连接到商店。您想要做的与您在 ExampleContainer 中所做的类似,即

export default connect(state => ({
   state: state.counter
 }),
 (dispatch) => ({
   actions: bindActionCreators(actions, dispatch)
 })
)(Launch);

然后正确的值将显示在您的日志中

关于ios - 将 react-native-router-flux 与 redux 一起使用,如何更新 View 组件中的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37253842/

相关文章:

javascript - 滚动 UI 时 UI 未更新

ios - 可以填充选择器 View 但不能从中获取数据

javascript - vue.js - 嵌套组件架构中的路由

javascript - 我可以将 Backbone 与 React Native 一起使用吗?

ios - 单击 IOS 后按钮标签颜色更改

javascript - 准确捕获移动端 'scrollend'事件

asp.net-mvc - MVC 3 - 新区域 - 404 错误 - 找不到资源 - 已尝试路由调试器

linux - 使用Linux,如何指定在哪个以太网接口(interface)上传输数据

javascript - 内部错误 : Metro Bundler has encountered an internal error [Duplicate Module]

react-native - 具有水平滚动和粘性列的 FlatList