Chapter 4: Gold challenge solution

I’m self-learning React and came up with this solution. It does seem to work. I wanted a sanity check to see if anyone else came up with the same or had a different approach.

App.js

import Header from './components/Header';
import ShuffleBtn from './components/ShuffleButton'
import Post from './components/Post';
import SelectedPost from './components/SelectedPost';
import Footer from './components/Footer';

import yellowCanary from './canary/yellow-canary.jpg';
import redCanary from './canary/red-canary.jpg';
import blueCanary from './canary/blue-canary.jpg';
import orangeCanary from './canary/orange-canary.jpg';
import { useState } from 'react';
import './App.css';

const canaryArray = [
  {image: yellowCanary, name: "Twinkle", id: 1}, 
  {image: redCanary, name: "Pepper", id: 2}, 
  {image: blueCanary, name: "Ocean", id: 3}, 
  {image: orangeCanary, name: "Sunny", id: 4}  
];


const wikiArray = [
  {url: "https://en.wikipedia.org/wiki/Atlantic_canary", id:1}, 
  {url: "https://en.wikipedia.org/wiki/Yellow_canary", id:2}
];

function App() {
  const [canaryArrayState,setCanaryArrayState] = useState(canaryArray);

  return (
    <div className="App">
      <Header />
      <ShuffleBtn canaryArrayState={canaryArrayState} setCanaryArrayState={setCanaryArrayState} />
      <div className='app-content'>

        <ul className='post-list'>
            {canaryArrayState.map((post) => (
              <Post key={post.id} image={post.image} name={post.name}  />
            ))}          
        </ul>
        <SelectedPost 
            name={canaryArray[0].name}
            image={canaryArray[0].image} />
      </div>
      {wikiArray.map((wikilist)=> (
          <Footer key={wikilist.id} url={wikilist.url} />
        ))}
    </div>
  );
}

export default App;

New component called ShuffleButton.js

function ShuffleButton ({canaryArrayState, setCanaryArrayState}){
    
    const handleClick = (canaryArray, setCanaryArray) => {
        //window.alert('You clicked ');
        let shuffleItem = canaryArray.shift();
        let newCanaryArry = [...canaryArray];
        newCanaryArry.push(shuffleItem);
        setCanaryArray(newCanaryArry); 
       }
    return (
        <button onClick={() => handleClick(canaryArrayState, setCanaryArrayState) }>Shuffle</button>
    );
}
export default ShuffleButton;

Your ShuffleButton component could be smaller since you don’t have to pass the arguments to handleClick as they are accessible from the outside context. Also, it should not shift until after it has spread the array because as is it’s modifying the incoming array, which is not ideal.
One other recommendation is to prefer const over let.
However, I’m not certain any of those things would have broken it.

Updated Shuffle:

function ShuffleButton ({canaryArrayState, setCanaryArrayState}){
    
    const handleClick = () => {
        //window.alert('You clicked ');
        const newCanaryArray = [...canaryArrayState];
        const shuffleItem = newCanaryArray.shift();
        newCanaryArray.push(shuffleItem);
        setCanaryArrayState(newCanaryArray); 
    };
    return (
        <button onClick={handleClick}>Shuffle</button>
    );
}
export default ShuffleButton;

Are you getting an error message in the console or can you describe more about what is not working?