使用 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 将反映状态的变化,而实际上它会记录旧的(当前)状态值。直到下一个渲染周期,更新的状态值才可用。见