[英]State Not Updating when Consuming React Custom Hook that Uses Axios with useReducer to Get Async Data
My app returns a "null is not an object" Render Error when consuming the useFetch custom hook that I made to get async data using axios .使用我为使用axios获取异步数据而制作的useFetch自定义钩子时,我的应用程序返回“null 不是对象”渲染错误。 The status , error , and data properties remains the same with their default values, I don't know if the problem is related to how I mutate my data or I'm not returning or consuming them properly.
status 、 error和data属性与它们的默认值保持一致,我不知道问题是否与我如何改变我的数据有关,或者我没有正确返回或使用它们。
// Axios config
import axios from "axios";
const instance = axios.create({
baseURL: "http://10.0.2.2:8000/api",
});
export default instance;
// Custom hook
import { useReducer, useEffect } from "react";
import axiosConfig from "../axiosConfig";
export default function useFetch(url) {
const initialState = {
status: "idle",
error: null,
data: null,
};
const [state, dispatch] = useReducer((state, action) => {
switch (action.type) {
case "FETCHING":
return { ...state, status: "fetching" };
case "FETCHED":
return { ...state, status: "fetched", data: action.payload };
case "FETCH_ERROR":
return { ...state, status: "error", error: action.payload };
default:
return state;
}
}, initialState);
useEffect(() => {
let cancelRequest = false;
if (!url) return;
function fetchData() {
dispatch({ type: "FETCHING" });
axiosConfig
.get(url)
.then((response) => {
if (cancelRequest) return;
dispatch({ type: "FETCHED", payload: response.data });
})
.catch((error) => {
if (cancelRequest) return;
dispatch({ type: "FETCH_ERROR", payload: error });
});
}
fetchData();
return function cleanup() {
cancelRequest = true;
};
}, [url]);
return [state];
}
// Consume custom hook
import React from "react";
import {
View,
Text,
StyleSheet,
TouchableOpacity,
Image,
ActivityIndicator,
} from "react-native";
import GlobalStyles from "../constants/GlobalStyles";
import { Entypo, EvilIcons } from "@expo/vector-icons";
import format from "date-fns/format";
import useFetch from "../utils/hooks/useFetch";
export default function TweetScreen({ route, navigation }) {
const [{ status, error, data: tweet }] = useFetch(
`/tweets/${route.params.tweetId}`
);
error && console.log(error);
function gotoProfile(userId) {
navigation.navigate("Profile Screen", { userId });
}
return (
<View style={GlobalStyles.container}>
{status === "fetching" ? (
<ActivityIndicator size="large" color="#007aff" />
) : (
<>
<View
style={[
GlobalStyles.flexRow,
GlobalStyles.spaceBetween,
styles.tweetContainer,
]}
>
<TouchableOpacity
style={GlobalStyles.flexRow}
onPress={() => gotoProfile(tweet.user.id)}
>
<Image
style={styles.avatar}
source={{ uri: tweet.user.avatar }}
/>
</TouchableOpacity>
</View>
</>
)}
</View>
);
}
Your data response is null.您的数据响应为空。 You can avoid getting undefind by saying
{ uri : tweet?.data.avatar }
, but I assume you should rather first destructure your useFetch correctly by doing const { data, error , loading } = useFetch(url)
.您可以通过说
{ uri : tweet?.data.avatar }
来避免不确定,但我认为您应该首先通过执行const { data, error , loading } = useFetch(url)
正确解构您的 useFetch。 If thats not going to help, then you should require(`${tweet?.data.avatar}`)
.如果那没有帮助,那么您应该
require(`${tweet?.data.avatar}`)
。 Hope that helps.希望有帮助。 Your code is really fragile though, you should debug first why you getting back null...
不过,您的代码确实很脆弱,您应该首先调试为什么要返回 null ...
Just solved this thing, turns out I just needed to do return state
instead of return [state]
as wrapping it inside an array causes the state to be stale.刚刚解决了这个问题,结果我只需要执行
return state
而不是return [state]
因为将它包装在数组中会导致状态过时。
So now I just consume the custom hook like this: const { status, error, data: tweet } = useFetch(...);
所以现在我只使用这样的自定义钩子:
const { status, error, data: tweet } = useFetch(...);
Instead of: const [{ status, error, data: tweet }] = useFetch(...);
而不是:
const [{ status, error, data: tweet }] = useFetch(...);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.