我有一个问题,我可能无法访问对象的值,可能是因为在程序获取数据并将其放入对象之前渲染了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]);
仍显示undefined
。Image: Results of console.log();
我猜它在获取数据和呈现页面的时间上可能存在一些问题。 (我知道useEffect
每当第二个参数中的变量更改时都会触发...)
如果能对此提供一些建议,我将不胜感激。
感谢您的阅读:)
其背后原因是您的axios呼叫正在响应[[asynchronously,因此您的likes
状态将在稍后更新。可能您可以使用useEffect()
钩子捕获更改。
useEffect()
通过此操作,一旦useEffect(() => { console.log('likes is ', likes); }, [likes]);
的状态发生变化,便会登录到控制台。我希望这会有所帮助!
如果(喜欢)“正在加载...”:未加载等...