javascript - 单击 Like 按钮后重新渲染反应组件(使用 Redux)
问题描述
我有以下 React 组件,它通过“renderPosts”方法显示所有用户的帖子。在它下方有一个喜欢/不喜欢按钮,用于显示当前登录的用户是否喜欢该帖子。
但是,当我单击like 按钮时,组件不会重新渲染,以便“renderPosts”方法创建一个不同的按钮,并且“like 字符串”按预期进行修改。只有当我转到另一个组件然后返回到该组件时,才会显示不同的按钮,反之亦然。
无论如何,我可以在我的应用程序中使用 Redux 解决这个问题吗?我在 onClick 事件之后尝试了 this.forceUpdate 但仍然无法正常工作......
我还尝试创建一个名为“likers”的新Reducer,根据robinsax,它基本上得到了喜欢特定帖子并将其作为道具导入组件但得到的用户数组
"this.props.likers.includes(currentUser)" is not a function
当app第一次到达主页(PostIndex)时,可能是因为this.props.likers仍然是reducer返回的一个空对象
这是我的动作创建者的代码:
export function likePost(username,postId) {
// body...
const request = {
username,
postId
}
const post = axios.post(`${ROOT_URL}/likePost`,request);
return{
type: LIKE_POST,
payload: post
}
}
export function unlikePost(username,postId){
const request = {
username,
postId
}
const post = axios.post(`${ROOT_URL}/unlikePost`,request);
return{
type: UNLIKE_POST,
payload: post
}
}
这是我的减速器:
import {LIKE_POST,UNLIKE_POST} from '../actions/index.js';
export default function(state = {},action){
switch(action.type){
case LIKE_POST:
const likers = action.payload.data.likedBy;
console.log(likers);
return likers;
case UNLIKE_POST:
const unlikers = action.payload.data.likedBy;
console.log(unlikers);
return unlikers;
default:
return state;
}
}
我真的很感激任何帮助,因为我是初学者
import { fetchPosts } from "../actions/";
import { likePost } from "../actions/";
import { unlikePost } from "../actions/";
class PostsIndex extends Component {
componentDidMount() {
this.props.fetchPosts();
}
renderPost() {
const currentUser = Object.values(this.props.users)[0].username;
return _.map(this.props.posts, post => {
return (
<li className="list-group-item">
<Link to={`/user/${post.username}`}>
Poster: {post.username}
</Link>
<br />
Created At: {post.createdAt}, near {post.location}
<br />
<Link to={`/posts/${post._id}`}>{post.title}</Link>
<br />
//error here, with this.props.likers being an
//array
{!this.props.likers.includes(currentUser) ? (
<Button
onClick={() => this.props.likePost(currentUser,post._id)}
bsStyle="success"
>
Like
</Button>
) : (
<Button
onClick={() => this.props.unlikePost(currentUser,post._id)}
bsStyle="warning"
>
Unlike
</Button>
)}{" "}
{post.likedBy.length === 1
? `${post.likedBy[0]} likes this`
: `${post.likedBy.length} people like this`}
</li>
);
});
}
function mapStateToProps(state) {
return {
posts: state.posts,
users: state.users,
likers: state.likers
};
}
}
解决方案
您需要使用 redux-thunk 中间件才能使用异步操作。首先,在创建 store 时添加 redux-thunk
import thunk from 'redux-thunk';
const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
然后像这样改变你的方法
export function likePost(username,postId) {
return function(dispatch) {
// body...
const request = {
username,
postId
}
axios.post(`${ROOT_URL}/likePost`,request)
.then(res => {
dispatch({
type: LIKE_POST,
payload: res
});
});
}
}
现在在 mapStateToProps 之后的组件中,定义 mapDispatchToProps,
const mapDispatchToProps = dispatch => {
return {
likePost: (currentUser,postId) => dispatch(likePost(currentUser, postId)),
// same goes for "unlike" function
}
}
export default connect(mapStateToProps, mapDispatchToProps)(PostsIndex);
推荐阅读
- uima - 使用 BooleanExpressions 进行变量赋值如何在 UIMA Ruta 中工作
- react-native - 使用(React Native Navigation)将数据发送到另一个组件
- android - 使用导航组件深度链接处理数组查询参数
- azure - Terraform 在不运行 az login 的情况下连接到 aks 集群
- sql-server - 使用 Entity Framework Core 了解对数据库表进行了哪些更改
- mysql - 如何将使用 docker 创建的 MySQL 连接到另一个端口(不是端口 3306)?
- javascript - 当我单击 rails-5.2 应用程序的“加载更多”按钮时,如何调整输出数据以显示在表格中?
- typescript - 导入时设置 tsconfig 默认路径
- python - 无法使用年和月过滤查询集
- linux - 在 Ubuntu 终端中启动 gams studio 的名称是什么?