我正在尝试在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状态,组件的属性都将保持为initialState。
答案 0 :(得分:4)
在redux
中,应避免直接改变减速器的状态。不要做类似state.reducers = blah
的事情。为了使redux
知道您正在尝试对state
进行更新,您需要返回一个全新的状态对象。遵循这些原则,减速器将正确更新,并且组件将获取新数据。
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
属性。
答案 1 :(得分:1)
可以尝试用这种方式编写的减速器:
const initialState = {
educations: []
};
export default function home(state = initialState, action){
switch(action.type){
case GET_EDUCATIONS:
return {
...state, educations:action.payload
}
default:
return state;
}
}
答案 2 :(得分:0)
您似乎正在简化化简器中的状态。如果更新了某些内容,reducer应该始终返回一个新的状态对象。
您可以按照上述答案的建议进行操作,但是我建议您使用immer(https://www.npmjs.com/package/immer)或immutable.js之类的软件包来防止任何错误。如果状态对象具有一些深层嵌套的属性,则使用传播语法可能很危险,而且很难100%确保没有意外地对某些内容进行突变,尤其是随着应用程序大小的增加。
答案 3 :(得分:0)
在我输入此字词时,您似乎已解决了这个问题-我决定将其张贴,因为这可能会有所帮助。
在克里斯托弗·恩戈(Christopher Ngo)所提到的内容之上,以下示例概述了如何与商店互动以创建新的教育,然后在单独的组件中进行查看。
干杯!
答案 4 :(得分:0)
我一直遇到这个问题,然后用 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 });
};
}