【问题标题】:Props not updating when redux state change in React Hooks当 React Hooks 中的 redux 状态更改时,道具不会更新
【发布时间】:2019-12-11 23:50:15
【问题描述】:

我正在尝试在 React Hooks 项目上实现 Redux,但它似乎效果不佳。我在这里做错了吗?

reducer.js

const initialState = {
    educations: []
};

export default function home(state = initialState, action){
    switch(action.type){
        case GET_EDUCATIONS: {
            state.educations = action.payload;
            return state;
        }
        default:
            return state;
    }
}

action.js

import * as types from '../constans/home';

export const getEducations = () => {
    return dispatch => {
        const edus = [
            {value: 1, name: 'Bachelor'},
            {value: 2, name: "Master"}
        ]

        dispatch({
            type: types.GET_EDUCATIONS,
            payload: edus
        })
    }
}

组件

import React, {useEffect} from 'react';
import {connect} from 'react-redux';
import {getEducations} from '../../redux/actions/home';

function Header({educations, getEducations}) { 
    useEffect(() => {
        getEducations(); //calling getEducations()
    }, [])

    useEffect(() => {
        console.log(educations) //console educations after every change
    })

    return (
        <div className="main-header">
        </div>
    )
}

const mapStateToProps = (state) => {
    return {
        educations: state.home.educations
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        getEducations: () => { dispatch(getEducations())}
    }
}

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

并且Header函数中的education属性总是一个空数组,如initialState。 当我使用Redux Devtools 检查浏览器时,它显示状态包含数组中的这两个对象。

所以无论我是否改变 redux 状态,组件的属性都将保持初始状态。

【问题讨论】:

  • 您介意将其放入 CodeSandbox 中吗?
  • @ErtanHasani,请参阅下面的解决方案,让我知道这是否适合您 :)

标签: reactjs redux react-redux state


【解决方案1】:

我一直遇到这个问题,并通过 CLEAR 然后 GET/SET 状态解决了这个问题。这确保了状态调用的重置。

Reducers.js

const initialState = {
    educations: []
};

export default function home(state = initialState, action){
    switch(action.type){
        case GET_EDUCATIONS: {
            return {
               ...state,
               educations: action.payload
            };
        }
        case CLEAR_EDUCATIONS: {
            return initialState;
        }
        default:
            return state;
    }
}

Hooks.js

...
const clearEducation = () => {
  dispatch({ type: CLEAR_EDUCATION });
}
   const getEducations = (payload) => {
      clearEducation(); // this clearing of the state is key fire re-render
      dispatch({ type: GET_EDUCATIONS, payload });
   };

}

【讨论】:

    【解决方案2】:

    看起来你已经解决了这个问题,而我正在输入这个 - 我决定无论如何都发布它,因为它可能会有所帮助。

    除了 Christopher Ngo 已经提到的内容之外,以下示例概述了您如何与商店交互以创建新的教育,然后在单独的组件中查看它们。..

    干杯!

    【讨论】:

      【解决方案3】:

      redux 中,你应该避免直接改变你的reducer 的状态。不要做类似state.reducers = blah 的事情。为了让redux 知道您正在尝试更新state,您需要返回一个全新的状态对象。遵循这些原则,您的 reducer 将正确更新,并且您的组件将获得新数据。

      Reducer.js

      const initialState = {
          educations: []
      };
      
      export default function home(state = initialState, action){
          switch(action.type){
              case GET_EDUCATIONS: {
                  return {
                     ...state,
                     educations: action.payload
                  };
              }
              default:
                  return state;
          }
      }
      

      在上面的代码中,我们返回了一个新的状态对象。它将包括现有state 中的所有内容,因此是...state,我们只需将educations 属性更新为action.payload

      【讨论】:

      • 现在效果很好。感谢您的解释和解决方案!
      【解决方案4】:

      看起来你正在改变 reducer 中的状态。如果有更新,reducer 应该总是返回一个新的状态对象。

      您可以按照上述答案的建议进行操作,但我建议使用 immer (https://www.npmjs.com/package/immer) 或 immutable.js 之类的包来防止出现任何错误。如果您的状态对象具有一些深度嵌套的属性,那么使用扩展语法可能会很危险,并且很难 100% 确定您没有意外地改变某些内容,尤其是当您的应用程序变大时。

      【讨论】:

        【解决方案5】:

        可以试试这样写的reducer:

        const initialState = {
                educations: []
            };
        
        export default function home(state = initialState, action){
            switch(action.type){
                case GET_EDUCATIONS: 
                return {
                    ...state, educations:action.payload
                }
        
                default:
                    return state;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-11-10
          • 2020-06-19
          • 1970-01-01
          • 2016-03-20
          • 2019-06-13
          • 1970-01-01
          • 2021-08-11
          • 1970-01-01
          相关资源
          最近更新 更多