0

I'm learning react for the first time, I have an app where it fetches some data from a public API. I currently have it show 10 cards with random items from the API, and I have added a button to fetch a random item from the API and add it to the array, I managed to get the new item added to the array using push() but it does not show in the app itself. How can I make it that the new item is shown in the app as well?

Here is my code

Home.js

import { useState, useEffect} from "react";
import Card from './Card';
const Home = () => {

    const [animals, setAnimals] = useState([]);

    const handleDelete = (id) => {
        const newAnimals = animals.filter(animal => animal.id !== id);
        setAnimals(newAnimals);
    }

    useEffect(() => {
        fetch('https://zoo-animal-api.herokuapp.com/animals/rand/10')
        .then(res => {return res.json()})
        .then(data => {
            setAnimals(data);
        });
    }, []);

    const handleAddAnimal = () => {
        fetch('https://zoo-animal-api.herokuapp.com/animals/rand/')
        .then(res => {return res.json()})
        .then(data => {
            animals.push(data);
            console.log(animals);
            //what to do after this
        })
    }

    return (
        <div className="home">
            <h2>Animals</h2>
            <button onClick={handleAddAnimal}>Add Animal</button>
            <Card animals={animals} handleDelete={handleDelete}/>
        </div>
      );
}

 
export default Home;

Card.js

const Card = ({animals, handleDelete}) => {
    // const animals = props.animals;

    return (  
        <div className="col-3">
        {animals.map((animal) => (
            <div className="card" key={animal.id}>
            <img
                src={animal.image_link}
                alt={animal.latin_name}
                className="card-img-top"
            />
            <div className="card-body">
                <h3 className="card-title">{animal.name}</h3>
                <p>Habitat: {animal.habitat}</p>
                <button onClick={() => handleDelete(animal.id)}>Delete Animal</button>
            </div>
        </div>
            ))}
    </div>
    );
}
 
export default Card;

App.js

import Navbar from './navbar';
import Home from './Home';

function App() {

  return (
    <section id="app">
      <div className="container">
      <Navbar />
      <div className="row">
        <Home />
      </div>
      </div>
    </section>
  );
}

export default App;

Screenshot of what I see now screenshot (I was also wondering how to fix the items going down instead of side by side but wanted to fix the add button first)

Let me know if there's anything else I should add, any help is appreciated, thank you!

2
  • Can you attach a screenshot of what you see right now? Commented Nov 24, 2022 at 6:04
  • Sure, I've edited my post and added a screenshot Commented Nov 24, 2022 at 6:19

2 Answers 2

2

Rather using array.push() method. You try using

setTheArray([...theArray, newElement]); e.g in your case it will be setAnimals([...animals,data]) in your onClick event.

Let me know doest it solve your issue or not.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! That worked, the new item was shown in the app.
0
 const handleAddAnimal = () => {
        fetch('https://zoo-animal-api.herokuapp.com/animals/rand/')
        .then(res => {return res.json()})
        .then(data => {
            setAnimals([...animals,data])
            console.log(animals);
            //what to do after this
        })
    }

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.