使用 React Natives 的 usestate 函数后,包含方法失败
Posted
技术标签:
【中文标题】使用 React Natives 的 usestate 函数后,包含方法失败【英文标题】:after using React Natives usestate function, includes method fails 【发布时间】:2021-12-04 07:09:54 【问题描述】:我正在尝试在我的 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>
);
【问题讨论】:
【参考方案1】:问题在于点击处理程序中的这一行
setFavs(favs.push(id))
将favs
设置为数字而不是数组。 Array#push()
在 push 后返回数组的新长度,而不是数组本身。见Why does Array.prototype.push return the new length instead of something more useful?。
另外,在状态数组上使用 push()
会改变数组,您应该改为
setFavs(prevFavs => [...prevFavs, id])
// or
setFavs(prevFavs => prevFavs.concat(id))
您的最后一个错误是假设在您的 setState
调用之后调用 console.log
将反映状态的变化,而实际上它会记录旧的(当前)状态值。在下一个渲染周期之前,更新的状态值将不可用。见Why calling react setState method doesn't mutate the state immediately?
【讨论】:
【参考方案2】:我认为这通常是因为组件最初渲染时,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 >
如果这能解决您的问题,请告诉我,谢谢
【讨论】:
感谢您的评论,这不是原因。 Pilchard 的方法成功了。【参考方案3】:我发现您的代码有两个问题。
首先,我没有看到您的useState
用法。应该是
const [favs, setFavs] = useState([]);
其次,您正在混合异步和同步代码。您正在调用getFavs
,其中包含对在主程序线程“外部”执行的异步存储的调用。之后您立即调用favs.includes()
,这当然不会起作用,因为异步调用尚未通过。
【讨论】:
以上是关于使用 React Natives 的 usestate 函数后,包含方法失败的主要内容,如果未能解决你的问题,请参考以下文章