React useEffect 不会在页面刷新后调度 redux 操作



我正在尝试呈现来自API的以下数据对象的数据。

{
"code": 0,
"c": "verified",
"d": "verified",
"leaseInfo": {
"infoId": 6
},
"cpfPrice": "500.00",
"carCurrentLocation": {
"id": 1,
"carId": "df47a56a395a49b1a5d06a58cc42ffc4"
},
"n": "verified",
"p": "false",
"ownerCarInfo": {
"brand": "Ferrari",
"model": "0"
},
"serviceFeeRate": 0.10,
"depositPrice": "100.00",
"pics": [
{
"picid": 49,
"carId": "df47a56a395a49b1a5d06a58cc42ffc4"
},
],
"items": {
"itemid": 5,
"carId": "df47a56a395a49b1a5d06a58cc42ffc4"
}
}

我使用react-redux来调度一个动作,我将在一个名为'carDetails'的状态下提供数据。

然而,当我尝试访问数据时,如果我的组件被刷新,carDetails变成undefined,因此给出"Cannot read property ownerCarInfo of undefined.">

我在我的React组件中获得和解构carDetails的数据:

import React, {useEffect} from 'react';
import { useDispatch, useSelector } from 'react-redux';
const CarInfo = ({ match }) => {
const dispatch = useDispatch();
const details = useSelector((state) => state.carDetails);
const { loading, carDetails } = details;
const {pics, carCurrentLocation, items, ownerCarInfo} = carDetails;
useEffect(() => {
dispatch(getCarDetails(match.params.id));
}, [dispatch, match]);
return (
<div>
{loading ? (
<Loader></Loader>
) : (
<>
<p>{d.depositPrice}</p>
<p>{ownerCarInfo.brand}</p>
</>
)}
</div>

);)

}

只要组件或React应用程序没有刷新,它就会检索数据并正确显示数据。一旦页面刷新,carDetails就会变成一个空数组。

这是getCarDetails()的动作:

export const getCarDetails = (id) => async (dispatch, getState) => {
try {
dispatch({
type: CAR_DETAILS_REQUEST,
});
const { userLogin } = getState();
const { userInfo } = userLogin;
const config = {
headers: {
Authorization: userInfo.token,
'Content-Type': 'application/json',
},
};
const { data } = await axios.get(
`${BASE_API}/car/info/getDetails/${id}/${userInfo.bscId}`,
config
);
dispatch({
type: CAR_DETAILS_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: CAR_DETAILS_FAIL,
payload:
error.response && error.response.data.msg
? error.response.data.msg
: error.msg,
});
}
};

这是我的减速机:

export const carsDetailsReducer = (state = { carDetails: [] }, action) => {
switch (action.type) {
case CAR_DETAILS_REQUEST:
return { loading: true };
case CAR_DETAILS_SUCCESS:
return { loading: false, carDetails: action.payload };
case CAR_DETAILS_FAIL:
return { loading: false, error: action.payload };
default:
return state;
}
};

这是我在redux store中声明carDetails的方式。

const reducer = combineReducers({
carDetails: carsDetailsReducer,
});

carDetails未定义和useEffect在页面刷新时不运行的原因是什么?

如果您使用axios你的动作应该是这样的async函数和await

如果您在api链接中传递API car id,则在参数中传递id:

import axios from "axios";

export const loadData = (id) => async (dispatch) => {
dispatch({
type: "CAR_DETAILS_REQUEST",
});
const detailData = await axios.get("http:\****/id");
dispatch({
type: "CAR_DETAILS_SUCCESS",
payload: {
success: detailData.data,
},
});
};

减速器:

const initailState = { carDetails: [], loading: true };
export const carsDetailsReducer = (state = initailState, action) => {
switch (action.type) {
case CAR_DETAILS_REQUEST:
return { ...state,
loading: true
};
case CAR_DETAILS_SUCCESS:
return {...state,
loading: false,
carDetails: action.payload 
};
case CAR_DETAILS_FAIL:
return { ...state,
loading: false, 
error: action.payload };
default:
return ...state;
}
};
你的<<p> strong> useEffect 应该只在获取数据时工作:
import React, {useEffect} from 'react';
import { useDispatch, useSelector } from 'react-redux';
const CarInfo = ({ match }) => {
const dispatch = useDispatch();
const details = useSelector((state) => state.carDetails);
const { loading, carDetails } = details;
const {pics, carCurrentLocation, items, ownerCarInfo} = carDetails;
useEffect(() => {
dispatch(getCarDetails(id));
}, [dispatch]);
return (
<div>
{loading ? (
<Loader></Loader>
) : (
<>
<p>{d.depositPrice}</p>
<p>{ownerCarInfo.brand}</p>
</>
)}
</div>

您也可以通过创建onclick()而不用useEffect来使用它。函数如下:

const loadDetailHandler = () => {
dispatch(getCarDetails(id));
};
return (
<div onClick={loadDetailHandler} >
</div>

如果carDetails初始状态是一个数组,那么为什么你在你的UI中解构对象属性?问题,下次再问……

如果在重新加载页面后状态恢复到初始状态,则空数组仍然是一个已定义对象。您需要跟踪导致state.carDetails.carDetails变为未定义的原因。如果您检查您的减速器,请注意您的CAR_DETAILS_REQUEST情况清除了carDetails状态,它变成了undefined。老实说,当你的代码正常运行而不重新加载页面时,我很惊讶你没有看到这个问题。

你需要保持这种状态。为了更好地测量,您应该总是在计算下一个状态对象时将复制现有状态,除非您有充分的理由省略部分状态。

export const carsDetailsReducer = (state = { carDetails: [] }, action) => {
switch (action.type) {
case CAR_DETAILS_REQUEST:
return {
...state, // <-- shallow copy existing state
loading: true,
};
case CAR_DETAILS_SUCCESS:
return {
...state, // <-- shallow copy existing state
loading: false,
carDetails: action.payload
};
case CAR_DETAILS_FAIL:
return {
...state, // <-- shallow copy existing state
loading: false,
error: action.payload,
};
default:
return state;
}
};

对于我来说,我认为你应该把状态保存在

`case CAR_DETAILS_REQUEST:
return {
...state, // <-- shallow copy existing state
loading: true,
};
`

能够在0之前使用它,当你想使用减速器时,你应该每种情况让旧状态下的减速器返回与初始状态相同的尖锐状态你也使用了加载并且在初始状态中没有找到
所以尝试创建状态的形状

state={
isloading:false,
carDetails: []
}

也尝试每次通过{...state ,is loading:true}

相同的状态

问题在CAR_DETAILS_REQUEST。您只返回{ loading: true };,因此carDetails将丢失并成为undefined

就像这样更新你的减速机:

case CAR_DETAILS_REQUEST:
return { ...state, loading: true };

相关内容

  • 没有找到相关文章

最新更新