checkBox and State

Viewed 43

hi i'm doing a little social network with reactjs

i've created an api with express ans sequelize where i can find the users and the messages that users have done

i want that on the wall, users can like a message

the route is done in my backend and it work but i have an issu with my front

when i want to check the checkox of a message all of theme are checked

i don't understand why all of my checkBox checked at the same time and i don't see how can i check only one and let the other do there life

here is the code

import React, { useEffect, useState } from 'react'
import './Wall.scss'
import axios from 'axios'
import {Link} from "react-router-dom"
import jwt_decode from "jwt-decode"


const token = localStorage.getItem('token')
const config = {
    headers: { authorization: `Bearer ${JSON.parse(token)}` }
}

const getAllMessage = 'http://localhost:3001/api/message/'



function Wall() {

    

    const [message, setMessage] = useState([])
 
    useEffect(() => {
            axios.get(getAllMessage, config)
           .then((res)=>{setMessage(res.data) ; console.log('useEffect')})
           .catch((err) => { console.log(err)})
    },[])


    const [isChecked, setIsChecked] = useState()

    const checkHandler = (e) =>{
        
        let item = e.target.closest('[data-id]')
        const disLikeMessage = `http://localhost:3001/api/like/dislike/${item.dataset.id}`
        const likeMessage = `http://localhost:3001/api/like/${item.dataset.id}`


        if(isChecked === item.checked){                  
            console.log('unchecked')
            axios.post(disLikeMessage,{}, config)
            .then((res)=>{setIsChecked(!isChecked)})
            .catch((err) => { console.log(err)})
        } else{       
            console.log('checked')
            axios.post(likeMessage,{}, config)
            .then((res)=>{setIsChecked(!isChecked)})
            .catch((err) => { console.log(err)})
        }        
      }



  return (
    <div className='containerWall'>
        <section className='cardWall'>
            <ul className='cardUl'>                
                {message.map(item =>(
                    <li key = {item.id} >
                        <div className ='cardMessage'>
                        <Link to = {`/Wall/Message/${item.id}`}>
                            <img src = {item.picture} alt="" className='cardImage'/>
                            <div className='cardContent'>
                            <h2>{item.title}</h2>
                            <p>{item.content} </p>
                            <p>{item.createdAt}</p>
                            </div>
                        </Link>
                            <div className='likeSystem'>
                                <input type="checkbox" className='like'data-id={item.id checked={isChecked} onChange={checkHandler} />
                                <p>{item.likes}</p>
                            </div>
                        </div>                        
                    </li>                   
                ))}
            </ul>
        </section>
    </div>
  )
}

export default Wall

HAve any idea how to solve this?

(ps i'm a react beginner so be easy on me i want to understand :) ty for your time )

1 Answers

You have a single state for all the checkbox so they all share the same isChecked value. If you want to keep one checked value in state per message, you could refactor it in its own component. A better approach would be to not store any checked state and just rely on the item.checked attribute, when it's updated, you refetch the messages and update the state. React query allows to do this very easily.

const Like = ({ item }) => {
  const [checked, setChecked] = useState(item.checked);

  function checkHandler({target}) {

    const url = `http://localhost:3001/api/like/${target.checked ? 'dislike/' + item.id : item.id}`
    axios
      .post(url, {}, config)
      .then((res) => {
        setChecked(prev => !prev);
      })
      .catch((err) => {
        console.log(err);
      });
  }

  return (
    <div className="likeSystem">
      <input
        type="checkbox"
        className="like"
        checked={checked}
        onChange={checkHandler}
      />
      <p>{item.likes}</p>
    </div>
  );
};
Related