В React.js функция onClick не отображает подробную информацию без обновления страницы

#javascript #html #node.js #reactjs #conditional-statements

Вопрос:

Я пытаюсь создать строку и кнопку «Не нравится» в React.js. У меня есть два тега, которые содержат значки Google, и при нажатии на значки они должны изменяться в режиме реального времени без необходимости обновлять страницу.

Но они не меняются без обновления страницы. Я использую MacBook Air и использую как браузер Safari, так и браузер Brave, но он не работает.

Кодировка моей страницы выглядит следующим образом :-

 
import React, { useState, useEffect, useContext } from 'react';
import {UserContext} from '../../App';

const Home = () => {

    const [data, setData] = useState([]);
    const { state, dispatch } = useContext(UserContext); // eslint-disable-line

    useEffect(() => {
        fetch('/allpost', {
            headers: {
                "Authorization": "Bearer "   localStorage.getItem("jwt")
            }
        }).then(res => res.json()).then(result => {
            setData(result.posts);
        });
    }, []);

    const likePost = (id) => {
        fetch('/like', {
            method: "put",
            headers: {
                "Content-Type": "application/json",
                "Authorization": "Bearer "   localStorage.getItem("jwt")
            },
            body: JSON.stringify({
                postId: id
            })
        }).then(res => res.json()).then(result => {
            const newData = data.map(item => {
                if (item._id == result._id) { // eslint-disable-line
                    return resu<
                } else {
                    return item;
                }
            })
            setData(newData);
        }).catch(err => {
            console.log(err);
        });
    }

    const dislikePost = (id) => {
        fetch('/dislike', {
            method: "put",
            headers: {
                "Content-Type": "application/json",
                "Authorization": "Bearer "   localStorage.getItem("jwt")
            },
            body: JSON.stringify({
                postId: id
            })
        }).then(res => res.json()).then(result => {
            const newData = data.map(item => {
                if (item._id == result._id) { // eslint-disable-line
                    return resu<
                } else {
                    return item;
                }
            })
            setData(newData);
        }).catch(err => {
            console.log(err);
        });
    }

    return (
        <div className="home">
            {
                data.map(item => {
                    return (
                        <div className="card home-card" style={{ borderRadius:"6px" }} key={item._id}>
                            <h6 style={{ paddingLeft: "10px", paddingTop:"10px", fontSize:"17px" }}>{ item.postedBy.name }</h6>
                            <div className="card-image">
                                <img src={ item.photo } style={{ paddingLeft:"6px", paddingRight:"6px" }} alt="Posted photograph" />
                            </div>
                            <div className="card-content">

                                {item.likes.includes(state._id)
                                    ?
                                        <i className="material-icons" style={{ color: "red" }} onClick={() => { dislikePost(item._id) }}>favorite_border</i>
                                    :
                                        <i className="material-icons" style={{ color: "red" }} onClick={() => {likePost(item._id)}}>favorite</i>
                                    
                                }
                                
                                <h6>{item.likes.length} likes</h6>
                                <h6>{ item.title }</h6>
                                <p>{ item.body }</p>
                                <input type="text" placeholder="Add a comment here." />
                            </div>
                        </div>
                    );
                })
            }
        </div>
    );
}

export default Home;

 

Я специально упоминаю, где написана моя логика изменения значка. Это выглядит следующим образом :

 
    <div className="card-content">

         {item.likes.includes(state._id)
              ?
               <i className="material-icons" style={{ color: "red" }} onClick={() => { dislikePost(item._id) }}>favorite_border</i>
              :
               <i className="material-icons" style={{ color: "red" }} onClick={() => {likePost(item._id)}}>favorite</i>
                                    
         }
                                
         <h6>{item.likes.length} likes</h6>
         <h6>{ item.title }</h6>
         <p>{ item.body }</p>
         <input type="text" placeholder="Add a comment here." />
    </div>

 

Комментарии:

1. Итак, проблема в том, что ваша логика обновляет только локальное data состояние, а не state предоставляется из контекста? Что конкретно state означает и state._id представляет собой?

2. Как отметил @DrewReese . Проблема здесь item.likes.includes(state._id) . так что при onClick, помимо запуска состояния, вам также необходимо обновить контекст .

Ответ №1:

Это не имеет отношения к данному вопросу . Но если вы готовы к рефакторингу, то я бы посоветовал вам изменить функции «Нравится» и «Не нравится» в одну функцию . Потому что обе функции выполняют одно и то же, за исключением того, что у них другой URL-адрес, который вы можете передать в качестве аргумента функции.

  const updatePostLikes = (id, url) => {
    fetch(url, {
      method: 'put',
      headers: {
        'Content-Type': 'application/json',
        Authorization: 'Bearer '   localStorage.getItem('jwt'),
      },
      body: JSON.stringify({
        postId: id,
      }),
    })
      .then((res) => res.json())
      .then((result) => {
        const newData = data.map((item) => {
          if (item._id == result._id) {
            // eslint-disable-line
            return resu<
          } else {
            return item;
          }
        });
        setData(newData);
      })
      .catch((err) => {
        console.log(err);
      });
  }
 

И когда вы нажмете на кнопку «Нравится» и «не нравится», теперь вы можете сделать это

 updatePostLikes(item._id, '/like') // for likes

updatePostLikes(item._id, '/dislike') // for dislikes