【发布时间】: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]); 仍然显示 undefined。
Image: Results of console.log();
我猜它获取数据和呈现页面的时间可能存在一些问题。 (我知道useEffect 每次第二个参数中的变量发生变化时都会触发......)
如果您能就此提供一些建议,我将不胜感激。
感谢阅读:)
【问题讨论】:
标签: javascript reactjs redux undefined associative-array