Ae Leung
Ae Leung

Reputation: 368

How to show data according to some state

In my react project, on the first row, I have a button that control what button to be shown. Second row is a button to trigger an api call. The response of the api call would be shown on the third line.

However, there is a problem. Let say, I have triggered button A once, and the according data is shown.

Then, I switched from button A to button B, and then I triggered the button B. the according data of B is shown.

However, when I switch back to button A, the data shown on the third row is still about button B.

In fact, even the first time I change the button from A to B, the data showing is from button A, it shouldn't be like that too.

Q:How could I change the data accordingly? (say I want the data to be shown is according to that button)

Here is some pictures

enter image description here

Button have already switch from A to B, but the data is still showing data from A.

enter image description here

Below is the code

import React, { useState, useEffect } from "react";
import axios from "axios";

export function App(props) {
  const [post, setPost] = useState("");
  const [showAButton, setShowAButton] = useState(true);

  useEffect(() => {
    console.log(post);
    console.log(showAButton);
  });

  const handleA = () => {
    axios
      .get("https://jsonplaceholder.typicode.com/todos/1")
      .then((response) => {
        setPost(response.data);
        //set the loading to be false as loading is done
      })
      .catch((err) => {});
  };

  const handleB = () => {
    axios
      .get("https://jsonplaceholder.typicode.com/todos/2")
      .then((response) => {
        setPost(response.data);
        //set the loading to be false as loading is done
      })
      .catch((err) => {});
  };

  return (
    <div className="App">
      <div>
        <button onClick={(e) => setShowAButton(!showAButton)}>
          Show Load data A button
        </button>
      </div>
      {showAButton ? (
        <>
          <button onClick={handleA}>Load data A</button>
          {post ? <Databoard post={post}></Databoard> : null}
        </>
      ) : (
        <>
          <button onClick={handleB}>Load data B</button>
          {post ? <Databoard post={post}></Databoard> : null}
        </>
      )}
    </div>
  );
}

const Databoard = (props) => {
  const { post } = props;
  return (
    <ul>
      <li>{post.userId}</li>
      <li>{post.id}</li>
      <li>{post.title}</li>
    </ul>
  );
};
// Log to console

Upvotes: 1

Views: 38

Answers (1)

Andrew Hulterstrom
Andrew Hulterstrom

Reputation: 1725

The problem is that the loaded data is being held in the state variable, post for both A and B. If you want to be able to switch between both bits of data, then you'll need to save both bits of data separately.

First, create useState variables to hold both dataA and dataB separately:

  const [dataA, setDataA] = useState("");
  const [dataB, setDataB] = useState("");

Then instead of calling setPost when you load the data, call the corresponding setDataA or setDataB for that data:

setDataA(response.data);

Then update the data display to show the data corresponding to the selected button:

      {showAButton ? (
        <>
          <button onClick={handleA}>Load data A</button>
          {dataA ? <Databoard post={dataA}></Databoard> : null}
        </>
      ) : (
        <>
          <button onClick={handleB}>Load data B</button>
          {dataB ? <Databoard post={dataB}></Databoard> : null}
        </>
      )}

That should do it!

Here's a full working example on CodeSandbox: Edit nifty-neumann-zrznzr

Upvotes: 2

Related Questions