计算状态碰巧晚了

Calculating state happens to late

我想做一个简单的点赞按钮,它有合适的颜色,取决于它是否被点赞。我尝试使用 React.useEffect 提前计算(在 return 之前),但似乎是在之后计算的...我可以看到它,因为所有的心,没有颜色,但是当我进行软重载时,它们会变成正确的颜色...有人知道我在这里做错了什么吗?

const Hart = ({subject}) => {
    const [liked, setLiked] = useState(false);
    const [hasloaded,setHasloaded] = useState(false);
    const [ownId, setOwnId] = useState('');
    const [token, setToken] = useState('');
    const [favourite, setFavourite] = useState([]);
    const favouriteId = [];
    React.useEffect(()=> {
        const constructor = async () => {
            await refreshToken();
          
          
              //favourites contains all the favorite subjects
              //This calculates the boolean to check if the subject is liked or not
              //This array is calculated with axios, and is correct
            for(let i = 0; i<favourite.length; i++) {
                if(favourite[i].id === subject.id) setLiked(true)
            }
            setHasloaded(true);
            console.log("done")
        }
        constructor();
    },[])

    if(!hasloaded) return null;
    else{
        return (
            <Pressable style= {styleSubjectList.heartIcon} onPress={() => checkFavorite()}>
                <MaterialCommunityIcons
                    name={liked ? "heart" : "heart-outline"}
                    size={20}
                    color={liked ? "red" : "white"}
                />
            </Pressable>
        );
    }
  };
  export default Hart;

函数 constructor 是异步的,您正在设置两个状态,这两个状态也是异步函数。因此,最终触发 setLiked 的 for 循环不会在 sethasLoaded 设置为 true 之前完成。您需要同步这两个操作。

const constructor = async () => {
   await refreshToken();
         
   for(let i = 0; i<favourite.length; i++) {
       if(favourite[i].id === subject.id) setLiked(true)
   }
}
constructor().then(() => setHasloaded(true)).catch(e => console.log(e))

React.useEffect(()=> {
        const constructor = async () => {
            await refreshToken();

            let token = await getAccessToken();
            setToken(token);
            let id = await getFromStore("ownId");
            id = removeFirstAndLast(id)
            setOwnId(id)

            const axios = require('axios' );
            const config = {
                method: 'get',
                url: backendURL + '/userManagement/users/' + id,
                headers: {
                    'Authorization': 'Bearer ' + JSON.parse(token)
                }
            };

            axios(config)
                .then(function (response) {
                    setFavourite(response.data.favouriteSubjects)
                    // console.log(response.data.favouriteSubjects)
                })
                .catch(function (error) {
                    console.log(error);
                });

            for(let i = 0; i<favourite.length; i++) {
                if(favourite[i].id === subject.id) setLiked(true)
            }
        }
        constructor().then(() => {
            setHasloaded(true);
            console.log("done");
        }).catch(e=>console.log(e));
    },[])