【问题标题】:ReactJS x Redux: Reducer not returning state valuesReactJS x Redux:Reducer 不返回状态值
【发布时间】:2017-07-10 04:41:46
【问题描述】:

大家好,我是 React 和 Redux 的新手。

我在尝试从数据库中获取用户对象时遇到了减速器问题。但它似乎没有将状态返回到正确的位置?

在我的前端 editProfile.js

import { a_fetchUser } from '../../../actions/resident/actions_user';

class EditProfile extends Component {
    componentDidMount() {
       this.props.fetchProfile({ iduser: this.props.auth.user.iduser });
       console.log(this.props.store.get('isProcessing')); // returns false
       console.log(this.props.store.get('retrievedUser')); // returns empty object {} when it's supposed to return data
    }

    // code simplified...

    const mapStateToProps = state => ({
       store: state.r_fetch_user,
       auth: state.authReducer
    });

    const mapDispatchToProps = (dispatch, store) => ({
       fetchProfile: (user) => {
           dispatch(a_fetchUser(user));
       }
    });

    export const EditProfileContainer = connect(
      mapStateToProps,
      mapDispatchToProps,
    )(EditProfile);
}

动作 actions_user.js

import axios from 'axios';

const startFetchUser = () => ({
    type: 'START_FETCH_USER',
});

const endFetchUser = response => ({
    type: 'END_FETCH_USER',
    response,
});

export const a_fetchUser = (user) => (dispatch) => {
    dispatch(startFetchUser());
    return axios.post('/rdb/getUser/', user)
        .then((res) => {
        console.log(res);
        dispatch(endFetchUser(res));
    })
    .catch((err) => {
        console.log(err);
        dispatch(endFetchUser({ status: 'error' }));
    });
};

Reducer userReducer.js

import Immutable from 'immutable';

export const fetchUserState = Immutable.Map({
    isProcessing: false,
    feedbackType: null,
    feedbackMsg: null,
    retrievedUser: {},
});

export const r_fetch_user = (state = fetchUserState, action) => {
    switch (action.type) {
        case 'START_FETCH_USER':
            console.log('start'); // printed
            return state.set('isProcessing', true);
        case 'END_FETCH_USER':
            if (action.response.data.status === 'success') {
                console.log(action.response.data.data[0]); // data retrieved from database successfully
                return state.set('isProcessing', false).set('retrievedUser', action.response.data.data[0]);
            } else {
                return state.set('isProcessing', false).set('retrievedUser', {});
            }
        default:
            return state;
    }
};

我的目标是从商店中检索对象 retrievedUser。我尝试在前端使用 console.log(this.props.store),它确实返回了初始状态的 Map,fetchUserState。

我也尝试过 state.set (不返回)并且它是成功的,所以我得出的结论是 return 语句有问题?

其他细节: 使用 MERN 堆栈。

【问题讨论】:

  • 你的根减速器在哪里?你为什么不使用 bindActionCreators?

标签: javascript reactjs redux react-redux


【解决方案1】:

这看起来不对:

 const mapDispatchToProps = (dispatch, store) => ({
       fetchProfile: (user) => {
           dispatch(a_fetchUser(user));
       }
    });

你需要做的是使用bindActionCreators,你可以看例子herehere

function mapDispatchToProps(dispatch) {
  return bindActionCreators(actionCreators, dispatch)
}

或者您也可以将语法更改为:

 const mapDispatchToProps = (dispatch) => ({
           fetchProfile: a_fetchUser(user);
 });

【讨论】:

  • 嗨,塔尔阿维萨!非常感谢你的帮助!我发现我的代码存在问题。这是因为我在从商店检索完成之前正在控制台记录。我在控制台日志记录之前添加了一个计时器,我的代码工作正常。感谢您介绍 bindActionCreators,它非常有帮助。干杯! :)
【解决方案2】:

我不确定你的 state.set() 方法到底做了什么(在 reducer 中),但如果它改变了状态,那么你的 reducer 将不会保持 PURE 函数,因为它改变了原始状态 obj。所以请更新下面的 reducer 方法以开始返回不应改变现有状态 obj 的新状态 obj:

export const r_fetch_user = (state = fetchUserState, action) => {
    switch (action.type) {
        case 'START_FETCH_USER':
            console.log('start'); // printed
            return state.set('isProcessing', true);
        case 'END_FETCH_USER':
            if (action.response.data.status === 'success') {
                console.log(action.response.data.data[0]); // data retrieved from database successfully
                return state.set('isProcessing', false).set('retrievedUser', action.response.data.data[0]);
            } else {
                return state.set('isProcessing', false).set('retrievedUser', {});
            }
        default:
            return state;
    }
};

【讨论】:

  • 嗨,纳夫尼特·戈埃尔!非常感谢你的帮助!我发现我的代码存在问题。这是因为我在从商店检索完成之前正在控制台记录。我在控制台日志记录之前添加了一个计时器,我的代码工作正常。至于您的建议,我认为设置状态不会改变状态。该功能仍然是纯的。再一次感谢你!干杯! :)
猜你喜欢
  • 2019-01-09
  • 1970-01-01
  • 2021-03-20
  • 1970-01-01
  • 1970-01-01
  • 2020-10-11
  • 2019-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多