使用 React Natives usestate 函数后,includes 方法失败
after using React Natives usestate function, includes method fails
我正在尝试在我的 React 本机代码中加入收藏夹机制,但我遇到了一个问题:
当页面首先呈现时,favs.includes
功能按预期工作。但是当我点击最喜欢的按钮时,它引发了一个错误
TypeError: favs.includes is not a function. (In 'favs.includes(id)', 'favs.includes' is undefined)
const getFavs = async () => {
await AsyncStorage.getItem("favs").then((res) => {
if (res !== [] && res !== null && res !== "") {
return setFavs(JSON.parse(res));
} else {
return setFavs([]);
}
});
};
useEffect(() => {
getFavs();
console.log(favs.includes(id));
return console.log(typeof favs);
}, []);
return (
<View style={{ alignItems: "center", justifyContent: "center" }}>
{favs.includes(id) ? (
<TouchableOpacity
onPress={() => {
AsyncStorage.removeItem("favs", id);
}}
>
<Icon name="star" size={25} color="orange" solid />
</TouchableOpacity>
) : (
<TouchableOpacity
style={{ height: 100, width: 100, backgroundColor: "red" }}
onPress={() => {
console.log(typeof favs);
setFavs(favs.push(id));
console.log(typeof favs);
AsyncStorage.setItem("favs", JSON.stringify(favs));
setFav(true);
}}
>
<Icon name="star" size={25} color="orange" />
</TouchableOpacity>
)}
</View>
);
我觉得一般是因为组件第一次渲染的时候,favs
状态还是空的,或者getFavs
异步函数没有完成。
也许您可以尝试为调用 favs.includes
的位置提供条件,例如:
{favs && favs.includes && favs.includes(id)? // make sure favs is truthy and favs.includes property existed
<TouchableOpacity onPress={()=>{
AsyncStorage.removeItem('favs',id);
}}>
<Icon name = "star" size={25} color="orange" solid />
</TouchableOpacity >
:
<TouchableOpacity
style={{height:100,width:100,backgroundColor:'red'}} onPress={()=>{
console.log(typeof(favs))
setFavs(favs.push(id))
console.log(typeof(favs))
AsyncStorage.setItem('favs',JSON.stringify(favs))
setFav(true)
}}>
<Icon name = "star" size={25} color="orange" />
</TouchableOpacity >
}
请告诉我这是否解决了您的问题,谢谢
我发现你的代码有两个问题。
首先,我没有看到您的 useState
用法。应该是
const [favs, setFavs] = useState([]);
其次,您混合了异步和同步代码。您正在调用 getFavs
,其中包含对在主程序线程“外部”执行的异步存储的调用。紧接着你正在调用 favs.includes()
,这当然是行不通的,因为异步调用还没有通过。
问题出在您的点击处理程序中的这一行
setFavs(favs.push(id))
将 favs
设置为数字而不是数组。 Array#push()
returns the new length of the array after push, not the array itself. see .
此外,在状态数组上使用 push()
会改变数组,您应该改为
setFavs(prevFavs => [...prevFavs, id])
// or
setFavs(prevFavs => prevFavs.concat(id))
你的最后一个错误是假设在你的 setState
调用之后调用 console.log
将反映状态的变化,而实际上它会记录旧的(当前)状态值。直到下一个渲染周期,更新的状态值才可用。见
我正在尝试在我的 React 本机代码中加入收藏夹机制,但我遇到了一个问题:
当页面首先呈现时,favs.includes
功能按预期工作。但是当我点击最喜欢的按钮时,它引发了一个错误
TypeError: favs.includes is not a function. (In 'favs.includes(id)', 'favs.includes' is undefined)
const getFavs = async () => {
await AsyncStorage.getItem("favs").then((res) => {
if (res !== [] && res !== null && res !== "") {
return setFavs(JSON.parse(res));
} else {
return setFavs([]);
}
});
};
useEffect(() => {
getFavs();
console.log(favs.includes(id));
return console.log(typeof favs);
}, []);
return (
<View style={{ alignItems: "center", justifyContent: "center" }}>
{favs.includes(id) ? (
<TouchableOpacity
onPress={() => {
AsyncStorage.removeItem("favs", id);
}}
>
<Icon name="star" size={25} color="orange" solid />
</TouchableOpacity>
) : (
<TouchableOpacity
style={{ height: 100, width: 100, backgroundColor: "red" }}
onPress={() => {
console.log(typeof favs);
setFavs(favs.push(id));
console.log(typeof favs);
AsyncStorage.setItem("favs", JSON.stringify(favs));
setFav(true);
}}
>
<Icon name="star" size={25} color="orange" />
</TouchableOpacity>
)}
</View>
);
我觉得一般是因为组件第一次渲染的时候,favs
状态还是空的,或者getFavs
异步函数没有完成。
也许您可以尝试为调用 favs.includes
的位置提供条件,例如:
{favs && favs.includes && favs.includes(id)? // make sure favs is truthy and favs.includes property existed
<TouchableOpacity onPress={()=>{
AsyncStorage.removeItem('favs',id);
}}>
<Icon name = "star" size={25} color="orange" solid />
</TouchableOpacity >
:
<TouchableOpacity
style={{height:100,width:100,backgroundColor:'red'}} onPress={()=>{
console.log(typeof(favs))
setFavs(favs.push(id))
console.log(typeof(favs))
AsyncStorage.setItem('favs',JSON.stringify(favs))
setFav(true)
}}>
<Icon name = "star" size={25} color="orange" />
</TouchableOpacity >
}
请告诉我这是否解决了您的问题,谢谢
我发现你的代码有两个问题。
首先,我没有看到您的 useState
用法。应该是
const [favs, setFavs] = useState([]);
其次,您混合了异步和同步代码。您正在调用 getFavs
,其中包含对在主程序线程“外部”执行的异步存储的调用。紧接着你正在调用 favs.includes()
,这当然是行不通的,因为异步调用还没有通过。
问题出在您的点击处理程序中的这一行
setFavs(favs.push(id))
将 favs
设置为数字而不是数组。 Array#push()
returns the new length of the array after push, not the array itself. see
此外,在状态数组上使用 push()
会改变数组,您应该改为
setFavs(prevFavs => [...prevFavs, id])
// or
setFavs(prevFavs => prevFavs.concat(id))
你的最后一个错误是假设在你的 setState
调用之后调用 console.log
将反映状态的变化,而实际上它会记录旧的(当前)状态值。直到下一个渲染周期,更新的状态值才可用。见