首页 > 解决方案 > 单击 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
    };
}
}

标签: javascriptreactjsredux

解决方案


您需要使用 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);

推荐阅读