reactjs - 在反应中获取未定义的错误值
问题描述
我想在我的应用程序中使用错误值作为警报。我的服务器响应也给了我正确的响应。但是在反应中使用时错误值显示未定义。
<b>Response Getting from API request</b>
{"success":false,"error":"Product Not Found"}
<b>code in react file</b>
const alert = useAlert();
const dispatch = useDispatch();
const { loading, error, products } = useSelector((state) => state.products);
useEffect(() => {
if (error) {
alert.error(error);
}
dispatch(getProduct());
}, [dispatch, error, alert]);
<b>Reducer</b>
export const productReducer = (state = { products: [] }, action) => {
switch (action.type) {
case ALL_PRODUCT_REQUEST:
return {
loading: true,
products: [],
};
case ALL_PRODUCT_SUCCESS:
return {
loading: false,
products: action.payload.products,
productsCount: action.payload.productsCount,
};
case ALL_PRODUCT_FAIL:
return {
loading: false,
error: action.payload,
};
case CLEAR_ERRORS:
return {
...state,
error: null,
};
default:
return state;
}
};
<b>action</b>
export const getProduct = () => async (dispatch) => {
try {
dispatch({ type: ALL_PRODUCT_REQUEST });
const { data } = await axios.get("/api/v1/products");
dispatch({
type: ALL_PRODUCT_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: ALL_PRODUCT_FAIL,
payload: error.response.data.message,
});
}
};
<b>store file</b>
import { createStore, combineReducers, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { composeWithDevTools } from "redux-devtools-extension";
import {
productReducer,
productDetailsReducer,
} from "./reducers/productReducer";
const reducer = combineReducers({
products: productReducer,
productDetails: productDetailsReducer,
});
let initialState = {};
const middleware = [thunk];
const store = createStore(
reducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);
export default store;
无法看到此功能工作警报。错误(错误)。当我控制台此错误时,它显示未定义。我想在出现错误时显示“未找到产品”警报。
解决方案
这是因为useSelector
实际上是从state
前端(由 Redux 管理)访问数据。这是从 API 获取后的数据,所以这纯粹是data
来自 API 的部分,而不是error
或loading
products
在这里,当您尝试访问state
. 它不会有类似的字段,loading
或者error
只有一个对象数组product
。
为了解决这个问题,你应该在你的 Redux 状态中以结构化的方式存储error
和loading
响应来自 API 的响应,然后你才能在每个访问此状态的 React 组件中访问它们。
例如代码:
const { loading, error, products } = useSelector((state) => {
// Curly braces with return should not be on next line
return {
loading: state.loading,
products: state.products,
error:state.error
});
另外,我建议使用react-query之类的包来很好地解决此类用例
选择
编写自己的钩子来处理此类异步任务
挂钩代码
import { useCallback, useEffect, useState } from "react"
export default function useAsync(callback, dependencies = []) {
const [loading, setLoading] = useState(true)
const [error, setError] = useState()
const [value, setValue] = useState()
// Simply manage 3 different states and update them as per the results of a Promise's resolution
// Here, we define a callback
const callbackMemoized = useCallback(() => {
setLoading(true)
setError(undefined)
setValue(undefined)
callback()
// ON SUCCESS -> Set the data from promise as "value"
.then(setValue)
// ON FAILURE -> Set the err from promise as "error"
.catch(setError)
// Irresp of fail or success, loading must stop after promise has ran
.finally(() => setLoading(false))
// This function runs everytime some dependency changes
}, dependencies)
// To run the callback function each time it itself changes i.e. when its dependencies change
useEffect(() => {
callbackMemoized()
}, [callbackMemoized])
return { loading, error, value }
}
在组件中使用这个钩子
import useAsync from "./useAsync"
export default function AsyncComponent() {
const { loading, error, value } = useAsync(() => {
// 3 states and their updated versions are returned while the promise is getting resolved
return new Promise((resolve, reject) => {
const success = false
setTimeout(() => {
success ? resolve("Hi") : reject("Error")
}, 1000)
})
})
return (
<div>
<div>Loading: {loading.toString()}</div>
<div>{error}</div>
<div>{value}</div>
</div>
)
}
推荐阅读
- mysql - 在nodejs mysql的选择查询中将数组作为值传递
- linux - 如何确定 systemd EnvironmentFile 将设置的精确环境变量集?
- python - 如何在 keras 顺序模型中获取来自未来的输出
- cypress - 在 Cypress 的 Save as 对话框中单击下载按钮后获取文件名
- c# - 在子节点使用 c# 解析 Soap XML 响应
- java - Spring Webflux - 使用Webflux webclient时不显示记录连接ID和新连接日志
- pip - 有什么方法可以使用 pip 获取没有版本信息的已安装模块?
- google-cloud-platform - 错误:无法部署资产“webhooks/ActionsOnGoogleFulfillment”
- java - 更改工具栏图标和工具提示 JavaSwing
- c# - Entity Framework Core 3.x 数据库首次设计,其中数据库设计时没有外键