Home > database >  React, upon button click, cycle through set number of results from data set
React, upon button click, cycle through set number of results from data set

Time:12-29

I have JSON results and need to return by id only four results at once. Using a button, upon click, I must display only the next four, repeatedly, until the end of the JSON dataset. I am not concerned with handling what happens once the end of the dataset is reached, although I'm all ears if there is a solution for that as well.

function App() {

  const [data, setData] = useState([])
  const [count, setCount] = useState(4)
  
  // MY QUESTION IS HERE
  const next4 = () => setCount(count   4)

  const API = "http://localhost:3001/sushis";
  const x = () => {
    fetch(API)
    .then(r => r.json())
    .then(k => setData(k))
  }
  
  useEffect(() => {
    x()
  }, [])

  return (
    <div className="app">
      <SushiContainer data={data}
                      count={count}
                      next4={next4} />
      <Table />
    </div>
  );
}





import React from "react";
import MoreButton from "./MoreButton";
import Sushi from "./Sushi"
// import { v4 } from "u  uid"

function SushiContainer({ data, count, next4 }) {
  return (
    <div className="belt">
      {data.slice(0, count).map(d => {
        return ( <Sushi key={d.id}
                        name={d.name}
                        img={d.img_url}
                        price={d.price}
                        created={d.created_at} /> )
      })}
      <MoreButton next4={next4} />
    </div>
  );
}

export default SushiContainer;

Upon page load I am shown the first four results. The problem comes next, when clicking a button to return only the next four. I have a callback set on the button, and with the code above which I highlighted, the callback serves to add the next four results to the first four, making eight total, which is not what I want.

[
  {
    "id": 1,
    "name": "Maguro Magic",
    "img_url": "./sushi/maguro.png",
    "price": 20,
    "created_at": "2018-07-27T18:53:16.241Z"
  },
  {
    "id": 2,
    "name": "Tsundere Ebi",
    "img_url": "./sushi/ebi.png",
    "price": 15,
    "created_at": "2018-07-27T18:53:16.244Z"
  },
  {
    "id": 3,
    "name": "Oh Sake",
    "img_url": "./sushi/sake.png",
    "price": 10,
    "created_at": "2018-07-27T18:53:16.248Z"
  },
  {
    "id": 4,
    "name": "Kawaii Tobiko",
    "img_url": "./sushi/tobiko.png",
    "price": 25,
    "created_at": "2018-07-27T18:53:16.251Z"
  },
  {
    "id": 5,
    "name": "Tsundere Ebi",
    "img_url": "./sushi/ebi.png",
    "price": 15,
    "created_at": "2018-07-27T18:53:16.255Z"
  },
  {
    "id": 6,
    "name": "Oh Sake",
    "img_url": "./sushi/sake.png",
    "price": 10,
    "created_at": "2018-07-27T18:53:16.258Z"
  },
  {
    "id": 7,
    "name": "Kawaii Tobiko",
    "img_url": "./sushi/tobiko.png",
    "price": 25,
    "created_at": "2018-07-27T18:53:16.260Z"
  },
  {
    "id": 8,
    "name": "Tsundere Ebi",
    "img_url": "./sushi/ebi.png",
    "price": 15,
    "created_at": "2018-07-27T18:53:16.264Z"
  },
}

I need to display ONLY data.id 1-4, then only 5-8, then only 9-12, and so on.

CodePudding user response:

Looks like you're handling which items to show in SushiContainer which you haven't added here. It depends on what's happening in SushiContainer but you should be able to only pass 4 data items at a time to it to solve your problem like so

<SushiContainer
  data={data.slice(count-4, count)}
  next4={next4}
 />

Note: this will create a new list reference on each render and will cause SushiContainer to re-render so it would be better to memoize the list before passing it

const currentData = useMemo(() => {
  return data.slice(count-4, count)
}, [data, count])

...

<SushiContainer
  data={currentData}
  next4={next4}
/>

  • Related