简体   繁体   中英

How i can do my component in React.js have a individual behavior?

I'm implementing a Like and Dislike Button, and I wanna that when I click them will be with other colors, but just the clicked component, when I click all buttons change the state, can anybody help me?

`

const indexPost = async () => {
        const data = await api.get('/api/posts')
        if(data.data.length !=0){
            const dataArray = data.data
            if(dataArray.length === 0) {
                return
            }else{
                return(
                    setPost(dataArray.map( data => (
                        <Post key={data._id} id={data._id} title={data.title} text={data.text}>
                            <Like id={data._id}></Like>
                        </Post>
                        
                    )))
               )
         }
     }
           
} 




export default function Like({itemId}) {
    const context = useContext(notificationContext)
    const {isLoved, Like, Loved, Unlike, isLike, isUnlike, setIsLike, setIsUnlike, setIsLoved } = context
    return(
                <div className={styles.likeContainer} key={itemId}>
                            {isLike ? (
                            <button className={styles.likeContent} onClick={() => setIsLike(false)}><Icon.ThumbsUp className={styles.Icon} fill="#5CB0BB" ></Icon.ThumbsUp></button>) : 
                            (<button className={styles.likeContent} onClick={() => Like() }><Icon.ThumbsUp className={styles.Icon}  ></Icon.ThumbsUp></button>)}
                            {isLoved ? 
                            (<button className={styles.likeContent} onClick={() => setIsLoved(false)}><Icon.Heart className={styles.Icon}   fill="red" ></Icon.Heart> </button>) : 
                            (<button className={styles.likeContent} onClick={() => Loved() }><Icon.Heart className={styles.Icon}  ></Icon.Heart></button>)}
                            {isUnlike ? (
                            <button className={styles.likeContent} onClick={() => setIsUnlike(false)}><Icon.ThumbsDown className={styles.Icon}  fill="#702BA6"  ></Icon.ThumbsDown> </button>) : 
                            (<button className={styles.likeContent} onClick={() => Unlike()}><Icon.ThumbsDown className={styles.Icon}  ></Icon.ThumbsDown></button>
                            )}
                     </div>                
    )
};

I have implemented the similar one in my project, it is very basic, it shows how to update the likes, you need to handle the cases of user authentication and stuff

App.js

import { useState, useEffect, createContext, useReducer } from "react";
import { updateArrayOfObj } from "./utils";
import AllPosts from "./AllPosts";
export const PostsContext = createContext();

const initialState = {
  posts: [
    {
      _id: "1",
      name: "Browny",
      image: "http://placekitten.com/200/310",
      likes: 0,
      love: 0,
      dislikes: 0
    },
    {
      _id: "2",
      name: "Blacky",
      image: "http://placekitten.com/200/320",
      likes: 0,
      love: 0,
      dislikes: 0
    },
    {
      _id: "3",
      name: "SnowWhite",
      image: "http://placekitten.com/200/300",
      likes: 0,
      love: 0,
      dislikes: 0
    }
  ]
};

const reducer = (state, action) => {
  switch (action.type) {
    case "UPDATE_POST":
      return {
        ...state,
        posts: updateArrayOfObj(
          state.posts,
          action.payload.obj,
          "_id",
          action.payload._id
        )
      };
    case "CREATE_POST":
      return {
        ...state,
        posts: [...state.posts, ...action.payload.data]
      };
    case "DELETE_POST":
      return {
        ...state,
        posts: state.posts.filter((ele) => ele._id !== action.payload._id)
      };
    default:
      return state;
  }
};
export default function App() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <PostsContext.Provider
      value={{
        state,
        dispatch
      }}
    >
      <div className="App">
        <AllPosts />
      </div>
    </PostsContext.Provider>
  );
}

PostsAll.js


import Post from "./Post";
import { PostsContext } from "./App";
import { useContext } from "react";

export default function AllPosts() {
  const { state } = useContext(PostsContext);
  return (
    <div className="allPosts">
      {state.posts.map((item) => {
        return (
          <Post
            name={item.name}
            image={item.image}
            likes={item.likes}
            love={item.love}
            dislikes={item.dislikes}
            id={item._id}
            key={item._id}
          />
        );
      })}
    </div>
  );
}


Post.js


import { PostsContext } from "./App";
import { useContext } from "react";

export default function Post(props) {
  const { state, dispatch } = useContext(PostsContext);
  const handleUserInteraction = (type, id) => {
    dispatch({
      type: "UPDATE_POST",
      payload: {
        obj: { [type]: props[type] + 1 },
        _id: id
      }
    });
  };
  return (
    <div className="post">
      <h3>{props.name}</h3>
      <img src={props.image} alt="cat" />
      <br />
      <button onClick={() => handleUserInteraction("likes", props.id)}>
        {props.likes} Like
      </button>{" "}
      <button onClick={() => handleUserInteraction("love", props.id)}>
        {props.love} Love
      </button>{" "}
      <button onClick={() => handleUserInteraction("dislikes", props.id)}>
        {props.dislikes} Dislike
      </button>
    </div>
  );
}


You can refer to this codesandbox to implement the same

编辑紧张之翼6f3nd

You can use onClick() on each like button and attach it with a function, then you can get the value of that particular like with e.currentTarget.id and change its css/style the way you want.

const handleClick=(e)=>
    {
    console.log(e.currentTarget.id);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM