对象的值在React中始终显示为“未定义”

问题描述 投票:0回答:2

我有一个问题,我可能无法访问对象的值,可能是因为在程序获取数据并将其放入对象之前渲染了DOM。

我正在尝试实施一个页面,您可以在其中看到所有用户的所有评论。在页面中,您还可以查看您已喜欢或不喜欢的评论。为了实现它,我想访问用户拥有的所有赞。

这是对象的初始状态。

const initialState = {
    likes: {},
};

并且将用从api服务器这样获取的数据填充该对象;

likes = {
    1: {id: 38, user_id: 3, review_id: 1, created_at: "2020-04-11T04:12:14.569Z", updated_at: "2020-04-11T04:12:14.569Z"}
    2: {id: 24, user_id: 3, review_id: 2, created_at: "2020-04-11T03:25:16.589Z", updated_at: "2020-04-11T03:25:16.589Z"}
    3: {id: 20, user_id: 3, review_id: 3, created_at: "2020-04-09T12:07:34.669Z", updated_at: "2020-04-09T12:07:34.669Z"}
}

[下面是表示评论的某些信息的组件,例如标题,用户名,喜欢的次数等。这些信息是从父组件继承而来的,并且带有道具“ review”。

<ReviewCard.js> 
const ReviewCard = props => {
    let { id, user_id, title, image, rate, good, likes_count, gameId, createdAt } = props.review;
    const userId = useSelector(state => state.authReducer.userId);
    .
    .
    .
    let favorite = <LikeButton 
                        likesCount={likes_count}
                        userId={userId} 
                        reviewId={id}
                    />

return (
        <Card className={classes.root}>
            <CardHeader
                .
                .
                .
                action={favorite}
                title={title}
                subheader={createdAt}
            />
    .
    .
    . 
);

LikeButton组件从字面上看是like按钮。我想根据用户是否已经喜欢评论来更改按钮的颜色。但是,if (likes[reviewId])始终被忽略,因为即使likes[reviewId]对象是用从api提取的实际数据填充的,undefined还是likes

<LikeButton.js>
const LikeButton = props => {
    let { likesCount, userId, reviewId } = props;
    const dispatch = useDispatch();
    const likes = useSelector(state => state.likeReducer.likes);

    const [count, setCount] = useState(likesCount);

    useEffect(() => {
        dispatch(actions.fetchLike(likes, userId, reviewId));
    }, [props, likes, count]);

    .
    .
    .

    console.log('likes is ', likes);
    console.log('reviewId is', reviewId);
    console.log(`like with reviewId = ${reviewId} is `, likes[reviewId]);

    let favorite = (
        <div className={classes.LikeButton}>
            <FavoriteBorderIcon 
                onClick={onLikeHandler}
                className={classes.Icon}
            />
            {count}
        </div>
    );

    if (likes[reviewId]) {
        favorite = (
            <div className={classes.LikeButton}>
                <FavoriteIcon 
                    onClick={onUnlikeHandler}
                    className={classes.FavoriteIcon}
                />
                {count}
            </div>
        );
    }

    return (
        <div>
            {favorite}
        </div>
    );
};

以下是与Redux相关的操作。

<./actions/like.js>
export const setLike = likes => {
    return {
        type: actionTypes.SET_LIKE,
        likes: likes,
    };
};

export const fetchLike = (likes, userId, reviewId) => {
    return dispatch => {
        const url = `http://localhost:3001/users/${userId}/reviews/${reviewId}/likes/1`;
        axios
            .get(url)
            .then(response => {
                likes[reviewId] = response.data; 
                dispatch(setLike(likes));
            })
            .catch(error => {
                console.log(error);
            });
    }
};

下面是与Redux相关的reduce。

<./reducer/like.js>
const initialState = {
    likes: {},
};

const setLike = (state, action) => {
    return updateObject(state, {
        likes: action.likes,
    });
};

const reducer = (state = initialState, action) => {
    switch (action.type) {
        case actionTypes.SET_LIKE:
            return setLike(state, action);
        default:
            return state;
    }
};

[类似获取用户拥有的likes后,它将存储在likes: {}中。实际上,一旦完成console.log('likes is ', likes);,LikeButton.js中的likes就会显示fetchLike()的内容。但是,带有reviewId = $ {reviewId}的console.log(仍为, likes[reviewId]);仍显示undefinedImage: Results of console.log();

我猜它在获取数据和呈现页面的时间上可能存在一些问题。 (我知道useEffect每当第二个参数中的变量更改时都会触发...)

如果能对此提供一些建议,我将不胜感激。

感谢您的阅读:)

javascript reactjs redux undefined associative-array
2个回答
0
投票

其背后原因是您的axios呼叫正在响应[[asynchronously,因此您的likes状态将在稍后更新。可能您可以使用useEffect()钩子捕获更改。

尝试以下操作:

useEffect()

通过此操作,一旦useEffect(() => {
   console.log('likes is ', likes);
}, [likes]);
的状态发生变化,便会登录到控制台。 

我希望这会有所帮助!


0
投票
使用带有if else语句的加载屏幕。

如果(喜欢)“正在加载...”:未加载等...

© www.soinside.com 2019 - 2024. All rights reserved.