【问题标题】:Reducer not changing state减速机不改变状态
【发布时间】:2019-01-30 04:11:06
【问题描述】:

以下是相关文件。 在reducer中,当它运行时...

 return {
   loggedIn: action.loggedIn
 };

我期待它用该信息替换状态。 当我在 LoginForm 中运行这段代码时,我得到了旧的状态输出。

this.props.onLogin();
console.log(this.props.loggedIn);

我希望我在这里忽略了一些简单的事情。其他一切似乎都按照我的预期工作。我可以直接在 切换使用...

state.loggedIn = action.loggedIn;

它按预期工作。谁能阐明我做错了什么?

动作

import { LOGGED_IN } from './actionTypes';

export const loggedIn = () => {
    return {
        type: LOGGED_IN,
        loggedIn: true,
    };
};

减速器

import {
  LOGGED_IN
} from "../actions/actionTypes";

const initialState = {
  loggedIn: false,
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case LOGGED_IN:
     return {
       loggedIn: action.loggedIn
     };
    default:
      return state;
  }
};

export default reducer;
import React, { Component } from 'react';
import { Text } from 'react-native';
import { Button, Card, CardSection, Input, Spinner } from './common';
import { Actions } from 'react-native-router-flux';
import firebase from '../Fire';
import { connect } from "react-redux";

import {
  loggedIn
} from "../store/actions";

登录表单 类 LoginForm 扩展组件 {

  onButtonPress() {
    this.onLoginSuccess();
  }

  onLoginSuccess() {
    this.props.onLogin();
    console.log(this.props.loggedIn);
    Actions.main({});
  }

  renderButton() {
    return (
      <Button onPress={this.onButtonPress.bind(this)}>
        Log in
      </Button>
    );
  }

  render() {
    return (
      <Card>
        <CardSection>
          <Input
            placeholder="user@gmail.com"
            label="Email"
        </CardSection>

        <CardSection>
          <Input
            secureTextEntry
            placeholder="password"
            label="Password"
          />
        </CardSection>

        <CardSection>
          {this.renderButton()}
        </CardSection>
      </Card>
    );
  }
}

const styles = {
  errorTextStyle: {
    fontSize: 20,
    alignSelf: 'center',
    color: 'red'
  }
};

const mapStateToProps = state => {
  return {
    loggedIn: state.loggedIn
  };
};

const mapDispatchToProps = dispatch => {
  return {
    onLogin: () => dispatch(loggedIn()),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);

配置存储

import { createStore, combineReducers } from 'redux';

import prolinkReducer from './reducers/prolink';

const rootReducer = combineReducers({
    loggedIn: prolinkReducer
});

const configureStore = () => {
    return createStore(rootReducer);
};

export default configureStore;

【问题讨论】:

  • 我不是 react/redux 专家,但我想知道 dispatch 函数是否是异步的,所以你调用 onLogin 并在 reducer 更新之前立即打印当前状态。尝试将 console.log(this.props.loggedIn) 包装在一个延迟 100 毫秒的 setTimeout 中,看看它是否打印出您期望的正确值,因为这表明调度是一个异步调用
  • 好主意,我会试试看的。
  • 没有运气尝试这个。
  • 你在使用多个reducer吗?我的意思是 combineReducers?
  • 我们使用 1 个 reducer 和 combineReducers。

标签: react-native redux react-redux


【解决方案1】:

您获得前一个值的原因是您在控制台记录前一个值。

当调用onLoginSuccess 时,this.props.loggedIn 的当前值将传递给console.log。我想如果你设置足够长的超时时间,那么它会显示它正在更新,但这并不是最好的检查方式。

componentDidUpdate

如果您想检查您的 redux 状态是否正在更新,您应该检查 componentDidUpdate https://reactjs.org/docs/react-component.html#componentdidupdate 中发生的情况

当您在mapStateToProps 中订阅loggedIn 时,这意味着您的组件在更新后将收到loggedIn 的新值。

在您的LoginForm.js 中添加以下内容:

componentDidUpdate(prevProps, prevState) {
  console.warn('previous', prevProps.loggedIn, 'current', this.props.loggedIn)
}

这将允许您在 loggedIn 更改时查看它的值。

react-native-debugger

您可以使用 react-native-debugger,其中包括 redux 检查工具。 https://github.com/jhen0409/react-native-debugger。这使您可以实时查看您的 redux 存储,这意味着您可以轻松跟踪更改,而无需求助于componentDidUpdate。但是,目前react-native-debugger 存在一个问题,这意味着它不适用于react-native 0.58.+,尽管有一个open pull request 可以解决该问题。

中间件

或者,您可以在您的 redux 设置中添加一个中间件,将每个事件记录到您的控制台。 https://redux.js.org/advanced/middleware,我之前用过redux-logger,它非常可定制,根据您的用例,您可能会发现它适合您的需求。

【讨论】:

  • 非常感谢!很好的解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
  • 1970-01-01
相关资源
最近更新 更多