useSelector() 在更新时不重新渲染组件

问题描述 投票:0回答:3

我有一个可以呈现患者信息的功能组件。在该组件中,在

useEffect
钩子中调度了 3 个操作,如下所示。每个操作都会发出异步网络请求。

useEffect(()=>{
        dispatch(fetchInpatient(patient_id));
        dispatch(fetchAllDoctors());
        dispatch(fetchVacantRooms());
    }, []);

我还使用

useSelector
来获取状态:

    const inpatient = useSelector(state => state.inpatient.inpatient);
    const doctors = useSelector(state => state.doctors.doctors);
    const vacantRooms = useSelector(state => state.vacantRooms.vacantRooms);

我的返回代码取决于这 3 个获取的状态。所以,它看起来像这样:

if(inpatient && doctors && vacantRooms){
        //render user info
}
else{
        //render loading icon
}

现在,最初

inpatients
doctors
vacantRooms
填充有默认状态或之前的状态。但是,当调度所有操作并更新状态时,
useSelector
不会重新渲染我的组件,因此它会显示上一个患者的信息,直到我手动刷新页面。解决这个问题的方法是什么?我究竟做错了什么?
这些是我的减速器:

export default (state = {} , action) => {
    switch(action.type){
        case 'FETCH_INPATIENT':
            return {...state , inpatient: action.payload};
        default:
            return state;
    }
}
export default (state = {} , action) => {
    switch(action.type){
        case 'FETCH_ALL_DOCTORS':
            return {...state , doctors: action.payload};
        default:
            return state;
    }
}
export default (state = {} , action) => {
    switch(action.type){
        case 'FETCH_VACANT_ROOMS':
            return {...state , vacantRooms: action.payload};
        default:
            return state;
    }
}

所有这些都在单独的文件中。我的

reducers/index
是这样的:

import{ combineReducers } from 'redux';
import inpatientsReducer from './inpatientsReducer';
import inpatientReducer from './inpatientReducer';
import allDoctorsReducer from './allDoctorsReducer';
import vacantRoomsReducer from './vacantRoomsReducer';

export default combineReducers({
    inpatients: inpatientsReducer,
    inpatient: inpatientReducer,
    doctors: allDoctorsReducer,
    vacantRooms: vacantRoomsReducer
});

我的

fetchInpatient(id)
动作创建器是:

export const fetchInpatient = (inpatient_id) => {
    return async (dispatch) => {
        const response = await axios.post('http://localhost:3001/api/inpatients/display' , {inpatient_id});
        dispatch({
            type: 'FETCH_INPATIENT',
            payload: response.data
        })
    }
}
reactjs redux react-redux
3个回答
4
投票

带有依赖数组

useEffect
[]
挂钩只会在组件第一次安装时运行一次。

您的获取操作取决于

patient_id
变量,因此您应该在依赖项中包含
patient_id


2
投票

对我来说

shallowEqual
没有
[]

import {
useSelector,
shallowEqual,
} from 'react-redux'
...
const inpatient = useSelector(state => state.inpatient.inpatient, shallowEqual);
const doctors = useSelector(state => state.doctors.doctors, shallowEqual);
const vacantRooms = useSelector(state => state.vacantRooms.vacantRooms, shallowEqual);

1
投票

2024年2月更新(基于react-redux v9.1.0)

如果您确定其他函数正常工作,您可以将

shallowEqual
作为第二个参数传递给
useSelector
函数。

import { useSelector, shallowEqual} from 'react-redux'

//...

const inpatient = useSelector(state => state.inpatient.inpatient, shallowEqual);
const doctors = useSelector(state => state.doctors.doctors, shallowEqual);
const vacantRooms = useSelector(state => state.vacantRooms.vacantRooms, shallowEqual);

//or pass it as the `equalityFn` field in the options argument

const inpatient = useSelector(state => state.inpatient.inpatient, {
  equalityFn: shallowEqual,
})

//for the other selectors like the above

或者使用您的自定义相等函数,如下所示:

import { useSelector } from 'react-redux'

// equality function
const customEqual = (oldValue, newValue) => oldValue === newValue

// later
const inpatient = useSelector(state => state.inpatient.inpatient, customEqual)

您可以在这里找到有关 redux hooks 的更多信息: Redux 钩子

© www.soinside.com 2019 - 2024. All rights reserved.