Реагировать не обновляя состояние на повторно используемый компонент? - PullRequest
0 голосов
/ 23 мая 2019

Я обновляю проект из стека MERN, который я закончил ранее.Он имеет кнопки «Нравится» и «Не нравится», которые обновляются в MongoDB, а затем на экран выводится обновленное количество лайков.Сейчас она обновляет базу данных, но не перерисовывает обновленную информацию на экране.

Например, я нажму кнопку «Мне нравится» в сообщении (должно быть от 2 лайков до 3).Я могу видеть обновленную информацию в MongoDB (3), но она никогда не добавляет подобное на экране (2).Кроме того, Redux DevTools сообщает, что не обновлял состояние автоматически (по-прежнему 2).Затем я нажимаю кнопку «Обновить» в моем браузере, и обновленное количество лайков уже есть (3).

Я использовал этот компонент и эти действия / редукторы в другом компоненте, и они отлично работают.По какой-то причине, он ведет себя по-другому здесь.Может быть, что-то делать с реквизитом, который я передаю?Проблема с UseEffect? ​​

Я попытался console.logging свойству лайков (post.likes) до и после компонента PostLikeAndDislike, и это одинаковое количество лайков в обоих случаях (то есть, если до клика 3, то это3 после нажатия).

Компонент PostLikeAndDislike:

const PostLikeAndDislike = ({
  addLike,
  removeLike,
  deletePost,
  auth,
  post: { _id, text, name, avatar, user, likes, comments, date },
  showActions
}) => (
  <div className="post bg-white p-1 my-1">
    <div>
      {showActions && (
        <Fragment>
          <button
            onClick={e => addLike(_id)}
            type="button"
            className="btn btn-light"
          >
            <i className="fas fa-thumbs-up" />{' '}
            {likes.length > 0 && <span>{likes.length}</span>}
          </button>
          <button
            onClick={e => removeLike(_id)}
            type="button"
            className="btn btn-light"
          >
            <i className="fas fa-thumbs-down" />
          </button>
        </Fragment>
      )}
    </div>
  </div>
)

PostLikeAndDislike.defaultProps = {
  showActions: true
}

const mapStateToProps = state => ({
  auth: state.auth
})

export default connect(
  mapStateToProps,
  { addLike, removeLike, deletePost }
)(PostLikeAndDislike)

Компонент PostLikeAndDislike импортируется в:

const Post = ({ getPost, post: { post, loading }, match }) => {
  useEffect(
    () => {
      getPost(match.params.id)
    },
    [getPost]
  )

  return loading || post === null ? (
    <Spinner />
  ) : (
    <Fragment>
      {console.log('Before', post.likes)}
      <PostLikeAndDislike post={post} showActions={true} />
      <div className="comments">
        {post.comments.map(comment => (
          <CommentItem key={comment._id} comment={comment} postId={post._id} />
        ))}
      </div>
      {console.log('After', post.likes)}
      <CommentForm postId={post._id} />
    </Fragment>
  )
}

const mapStateToProps = state => ({
  post: state.post
})

export default connect(
  mapStateToProps,
  { getPost, addLike, removeLike }
)(Post)

Действия:

// Get post
export const getPost = id => async dispatch => {
  try {
    const res = await axios.get(`/api/posts/${id}`)

    dispatch({
      type: GET_POST,
      payload: res.data
    })
  } catch (err) {
    dispatch({
      type: POST_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status }
    })
  }
}

// Add like
export const addLike = id => async dispatch => {
  try {
    const res = await axios.put(`/api/posts/like/${id}`)

    dispatch({
      type: UPDATE_LIKES,
      payload: { id, likes: res.data }
    })
  } catch (err) {
    dispatch({
      type: POST_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status }
    })
  }
}

// Remove like
export const removeLike = id => async dispatch => {
  try {
    const res = await axios.put(`/api/posts/unlike/${id}`)

    dispatch({
      type: UPDATE_LIKES,
      payload: { id, likes: res.data }
    })
  } catch (err) {
    dispatch({
      type: POST_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status },
      loading: false
    })
  }
}

Reducer:

const initialState = {
  posts: [],
  post: null,
  loading: true,
  error: {}
}
case GET_POST:
  return {
    ...state,
    post: payload,
    loading: false
}
case UPDATE_LIKES:
  return {
    ...state,
    posts: state.posts.map(
      post =>
        post._id === payload.id ? { ...post, likes: payload.likes } : post
   )
}

Как я уже говорил выше, я ожидаю, что кнопки «Мне нравится» и «Не нравится» изменят количество лайков и немедленно отобразят его на экране.

Заранее спасибо!

...