【问题标题】:The value of the object always shows "undefined" in React对象的值在 React 中总是显示“未定义”
【发布时间】:2020-04-13 11:56:00
【问题描述】:

我无法访问对象的值的问题可能是因为在程序获取数据并将其放入对象之前渲染了 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"}
}

下面是代表评论的一些信息的组件,例如标题,用户名,点赞数等。这些信息是从带有“评论”属性的父组件继承而来的。

<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]undefined,即使在 likes 对象填充了从 api 获取的实际数据之后。

<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 的 like-related reducer。

<./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;
    }
};

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

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

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

感谢阅读:)

【问题讨论】:

    标签: javascript reactjs redux undefined associative-array


    【解决方案1】:

    这背后的原因是您的 axios 调用正在响应 异步,因此您的 likes 状态将稍后更新。或许您可以使用useEffect() 钩子捕获更改。

    尝试如下:

    useEffect(() => {
       console.log('likes is ', likes);
    }, [likes]);
    

    通过这样做,您的likes 将在状态发生更改后登录到控制台。

    我希望这会有所帮助!

    【讨论】:

    • 感谢您的评论!我试过了,并且能够捕捉到变化。如何确保先更新likes,然后再更新likes[reviewId]
    【解决方案2】:

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

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

    【讨论】:

    • 感谢您的评论 :) 你能更具体一点吗?这如何解决问题?
    猜你喜欢
    • 2021-05-28
    • 2019-11-03
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多