Search code examples
arraysreactjsfetch

Playing with randomly returned item from fetch api object issue


Before I'm hit with a possible duplicate tag hear me out.

I have the code

 const [value, setValue] = useState();
 const [data, setData] = useState();

  const handleChange = (e) => {
    setValue(e.target.value);
  };


  const handleClick = () => {
    const options = {
      method: 'GET',
      headers: {
        'X-RapidAPI-Host': 'advanced-movie-search.p.rapidapi.com',
        'X-RapidAPI-Key': 'myKeyHere'
      }
    };
    
    fetch(`https://advanced-movie-search.p.rapidapi.com/discover/movie? 
       with_genres=${value}&page=18`, options)
      .then(response => response.json())
      .then(response => {
        let res = response
        setData(res)
        console.log(res)
      })  
      .catch(err => console.error(err));
  };

// then returning this here like this.

    <div className="card">
        <h2>{data?.results?.[Math.floor(Math.random() * data.results.length)].title}</h2>
        <p>{data?.results?.[Math.floor(Math.random() * data.results.length)].overview}</p>
      </div>

as you can see here I'm calling an api which returns an array of 20 items then randomly selecting one every time the button is clicked. as you can probably tell from the p tag which is running the same random selection this too will pull a random "overview" from any of the 20 objects from the array.

What I'm trying to is once the title is pulled randomly in the h2 then all other data I call will come from only that object.

What I thought would would is to take the object that gets called and save it to a state then call it with state.overview or whatever I have no idea if that will work or how to even do it though.

Thanks in advance!


Solution

  • Here is my solution:

    • move the api call to an useEffect without dependencies to run only on mount (completely optional)
    • create a new state to store a random number, let's say currentResult
    • on every button click, generate a random number an save it into currentResult using setCurrentResult
    • refactor the render template to use data?.results?[currentResult]...
      const [value, setValue] = useState();
      const [data, setData] = useState();
      const [currentResult, setCurrentResult] = useState(null);
    
      const handleChange = (e) => {
        setValue(e.target.value);
      };
    
      const handleClick = () => {
        // Fetch if you want
    
        setCurrentResult(Math.floor(Math.random() * data.results.length))
      };
    
    // then returning this here like this.
    
    {currentResult && (
      <div className="card">
        <h2>{data?.results?.[currentResult].title}</h2>
        <p>{data?.results?.[currentResult].overview}</p>
      </div>
    )}