1

I've been following a tutorial about update a value, it increments the value when the user clicks a button.

But, I have the JSON object value to be updated. The value should be updated when the user clicks a button and vice versa. After I tried to implements following the example, it not changed. Here's my code:

1. onClick:

<div>
  Point: {item.point}&emsp;
  <button onClick={() => setCount(item.point + 1)} class="btn"><i class="fa fa-arrow-up"></i></button>
  <button onClick={() => setCount(item.point - 1)} class="btn"><i class="fa fa-arrow-down"></i></button>
</div>

2. useState:

const [count, setCount] = useState(0);

3. comments.json:

{
        "id": "fa1ca3c1-cc1e-4ed9-86b8-f60d8312d499",
        "author": "Neal Topham",
        "avatar": "http://lorempixel.com/100/100/people/1/",
        "date": "2017-02-08T00:30:05.552Z",
        "message": "Mungkin ada fenomena paranormal yang tidak bisa dijelaskan. Lebih baik nyala mati sendiri daripada tidak nyala sama sekali",
        "point": 3,
}

4. Tutorial Link:

https://reactjs.org/docs/hooks-state.html

1

4 Answers 4

2

You will probably need your object to live in your state in your case.

useState

const [message, setMessage] = useState({
  "id": "fa1ca3c1-cc1e-4ed9-86b8-f60d8312d499",
  "author": "Neal Topham",
  "avatar": "http://lorempixel.com/100/100/people/1/",
  "date": "2017-02-08T00:30:05.552Z",
  "message": "Mungkin ada fenomena paranormal ...",
  "point": 3,
});

You cannot mutate part of the state, so you will basically make a modified copy of it.

const addCount = (n) => {
  setMessage({
    ...message,
    point: message.point + n
  });
};

<div>
  Point: {message.point}&emsp;
  <button onClick={() => addCount(1)} class="btn"><i class="fa fa-arrow-up"></i></button>
  <button onClick={() => addCount(-1)} class="btn"><i class="fa fa-arrow-down"></i></button>
</div>
Sign up to request clarification or add additional context in comments.

2 Comments

The JSON object is in comments.json file
I'm new to react. Your answer is very clear. "...message" gives the JSON current object and then added "point" element replace its point element. That's what I needed. Thanks!
2

1. useState:

const [items, setItems] = useState([]);

2. Modified Button:

<button
  onClick={() => {
   // first, clone it
    const newItems = [...items];
    newItems[idx] = {
      ...item,
      point: item.point + 1
    };
    setItems(newItems);
  }}
  className="btn-upvote"
>
  <i className="fa fa-arrow-up"></i>
</button>

 <button
  onClick={() => {
    // first, clone it
    const newItems = [...items];
    newItems[idx] = {
      ...item,
      point: item.point - 1
    };
    setItems(newItems);
  }}
  className="btn-downvote"
>
  <i className="fa fa-arrow-down"></i>
</button>

Comments

0

Use count instead of item.point.

const [count, setCount] = useState(item.point);
<div>
  Point: {count}&emsp;
  <button onClick={() => setCount(item.point + 1)} class="btn"><i class="fa fa-arrow-up"></i></button>
  <button onClick={() => setCount(item.point - 1)} class="btn"><i class="fa fa-arrow-down"></i></button>
</div>

Comments

0

The problem is that your onClick listeners update the count variable while you're rendering item.point.

At this point React simply renders the point property of the item object, which is not bound to any change of the count state variable.

Depending on your application logic you might want to extract the item.point directly into count variable like this:

const [count, setCount] = useState(item.point);

and render {count} instead of {item.point}

However this approach will work only in one direction, meaning that when you click on the button the rendered value will change, but it will not update the actual point property of the item object

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.