*any fuction* "is not a function" Reactjs fetch - javascript

i've tried to make a fetch and take one element of the data base by id on Reactjs, backend with javascript(node + express + sequelize), but i had some problems and i couldn't at anytime. im searched on google but i dont know hot to apply the solutions on my code... here some examples of my trying:
import { useState } from "react";
import { useParams, Link } from "react-router-dom";
import "./detallesBarrio.css";
const BarriosDetails = () => {
const { id } = useParams();
const [barrio, setBarrio] = useState({});
const loadBarrioDetails = () => {
fetch("http://localhost:3001/api/barrios")
.then((x) => x.json())
.then((y) => y.data)
// .then((z) => console.log(z))
.then((allBarrio) => setBarrio(allBarrio));
};
let byid = barrio.filter(obj => {
return obj.id === id;
});
console.log(byid);
loadBarrioDetails();
return (
<main className="barrio-details">
{byid.map(obj => {
return (
<div key={obj.id}>
<div>
<h1>Detalles de {obj.nombre}</h1>
<img src={obj.foto} alt="imagen no disponible" />
<article>
<Link to="/barrios">Volver</Link>
</article>
</div>
</div>
);
})}
</main>
);
};
export default BarriosDetails;
also my tryings:
-no filter function (problem: map is not a function)
import { useState } from "react";
import { useParams, Link } from "react-router-dom";
import "./detallesBarrio.css";
const BarriosDetails = () => {
const { id } = useParams();
const [barrio, setBarrio] = useState({});
const loadBarrioDetails = () => {
fetch(`http://localhost:3001/api/barrios`)
.then((x) => x.json())
.then((y) => y.data)
// .then((z) => console.log(z))
.then((allBarrio) => setBarrio(allBarrio));
};
loadBarrioDetails();
return (
<main className="barrio-details">
{barrio.map((barri) => {
return (
<div key={barri.id}>
<div>
<h1>Detalles de {barri[id].nombre}</h1>
<img src={barri[id].foto} alt="imagen no disponible" />
<article>
<Link to="/barrios">Volver</Link>
</article>
</div>
</div>
);
})}
</main>
);
};
export default BarriosDetails;
-no maping (problem: the code dont recognise 'nombre'(database camp') on '{barrio[id].nombre}')
import { useState } from "react";
import { useParams, Link } from "react-router-dom";
import "./detallesBarrio.css";
const BarriosDetails = () => {
const { id } = useParams();
const [barrio, setBarrio] = useState({});
const loadBarrioDetails = () => {
fetch(`http://localhost:3001/api/barrios`)
.then((x) => x.json())
.then((y) => y.data)
.then((z) => console.log(z))
.then((allBarrio) => setBarrio(allBarrio));
};
loadBarrioDetails();
return (
<main className="barrio-details">
<div>
<h1>Detalles de {barrio[id].nombre}</h1>
<img src={barrio[id].foto} alt="imagen no disponible" />
<article>
<Link to="/barrios">Volver</Link>
</article>
</div>
</main>
);
};
export default BarriosDetails;
yes console.log give me the correct array

You are getting map is not a function because you're initiating the state as an object. is should be useState([]) instead of useState({})
based on your code you want to filter by id and id is unique so it's better to use array.find(obj => obj.id === id) than using array.filter().
in your first snippet let byid = barrio.filter(obj => { return obj.id === id; }); is executed before running the fetch and loading data.
try using useEffect for this kind of needs and loading data as a side effect after mounting the component and you should check the existance of an object or array before accessing it useEffect(() => loadBarrioDetails(), [])
Or since you just need one single object you can use like this:
import { useState } from "react";
import { useParams, Link } from "react-router-dom";
import "./detallesBarrio.css";
const BarriosDetails = () => {
const { id } = useParams();
const [barrio, setBarrio] = useState(null);
const loadBarrioDetails = () => {
fetch(`http://localhost:3001/api/barrios`)
.then((x) => x.json())
.then((y) => y.data)
.then((allBarrio) => {
const byId = allBarrio.find(obj => obj === id);
setBarrio(byId ?? null);
});
};
useEffect(() => loadBarrioDetails(), []);
if (!barrio) return <></> // anything to display that the data is loading or doesn't exist depends on you need.
return (
<main className="barrio-details">
<div>
<h1>Detalles de {barrio.nombre}</h1>
<img src={barrio.foto} alt="imagen no disponible" />
<article>
<Link to="/barrios">Volver</Link>
</article>
</div>
</main>
);
};
export default BarriosDetails;

Related

While rendering a component it is showing an error- "Cannot update a component (`App`) while rendering a different component (`EventList`). "

I Can't render my events. Its showing this error -
"Cannot update a component (App) while rendering a different component (EventList). To locate the bad setState() call inside EventList, follow the stack trace as described in https://reactjs.org/link/setstate-in-render"
Here is EventList Component code -
import { useEffect, useState } from "react";
import EventList from "../../event-list";
import EventForm from "../event-form";
const EventAction = ({
getEventsByClockID,
addEvent,
updateEvent,
clockID,
deleteEvent,
deleteEventsByClockID,
}) => {
const [isCreate, setIsCreate] = useState(false);
const [isToggle, setIsToggle] = useState(false);
const [eventState, setEventState] = useState(null)
const handleCreate = () => {
setIsCreate(!isCreate);
}
useEffect(() => {
setEventState(getEventsByClockID(clockID, true));
}, [isToggle])
const handleToggle = () => {
setIsToggle(!isToggle);
}
return (
<div>
<div>
<button onClick={handleCreate}>Create Event</button>
<button onClick={handleToggle}>Toggle Events</button>
</div>
{isCreate && (
<>
<h3>Create Event</h3>
<EventForm
clockID={clockID}
handleEvent={addEvent}
/>
</>
)}
{isToggle && (
<>
<h3>Events of this clock</h3>
<EventList
clockID={clockID}
eventState={eventState}
deleteEvent={deleteEvent}
updateEvent={updateEvent}
deleteEventsByClockID={deleteEventsByClockID}
/>
</>
)}
</div>
)
}
export default EventAction;
Here is my App Component Code -
import ClockList from "./components/clock-list";
import LocalClock from "./components/local-clock";
import useApp from "./hooks/useApp";
import { localClockInitState } from "./initialStates/clockInitState";
const App = () => {
const {
localClock,
clocks,
updateLocalClock,
createClock,
updateClock,
deleteClock,
getEventsByClockID,
addEvent,
deleteEvent,
updateEvent,
deleteEventsByClockID,
} = useApp(localClockInitState);
return (
<div>
<LocalClock
clock={localClock}
updateClock={updateLocalClock}
createClock={createClock}
/>
<ClockList
clocks={clocks}
localClock={localClock.date}
updateClock={updateClock}
deleteClock={deleteClock}
getEventsByClockID={getEventsByClockID}
addEvent={addEvent}
deleteEvent={deleteEvent}
updateEvent={updateEvent}
deleteEventsByClockID={deleteEventsByClockID}
/>
</div>
)
}
export default App;
and Here is my useApp hook -
import { useState } from "react";
import deepClone from "../utils/deepClone";
import generateID from "../utils/generateId";
import useEvents from "./useEvents";
const getID = generateID('clock');
const useApp = (initValue) => {
const [localClock, setLocalClock] = useState(deepClone(initValue));
const [clocks, setClocks] = useState([]);
const {
// events,
// getEvents,
getEventsByClockID,
addEvent,
deleteEvent,
deleteEventsByClockID,
updateEvent,
} = useEvents();
const updateLocalClock = (data) => {
setLocalClock({
...localClock,
...data,
})
}
const createClock = (clock) => {
clock.id = getID.next().value;
setClocks((prev) => ([
...prev, clock
]))
}
const updateClock = (updatedClock) => {
setClocks(clocks.map(clock => {
if(clock.id === updatedClock.id) return updatedClock;
return clock;
}));
}
const deleteClock = (id) => {
setClocks(clocks.filter(clock => clock.id !== id));
}
return {
localClock,
clocks,
updateLocalClock,
createClock,
updateClock,
deleteClock,
getEventsByClockID,
addEvent,
deleteEvent,
updateEvent,
deleteEventsByClockID,
}
}
export default useApp;
I want to show all events incorporated with each individual clock.

How can I change the state of individual elements in a map function?

I want the content to display when the tab is clicked. The issue that I'm having is that once the tab is clicked, all the tabs open... and likewise close when clicked again. I've been trying for hours to figure out how to fix this. I thought I had an answer by having a state that I could set the index to and then write a condition for the tab to open when the index of the state is the same but I noticed that after clicking on another tab, the other one closes. I would appreciate it so much if someone could help me open an individual tab when it's clicked and always stay open until clicked again, meaning, I could have multiple tabs open at once.
Here's a demo:
https://codesandbox.io/s/orrigenda-react-question-5oxg47
import React, { useEffect, useState } from 'react'
import axios from 'axios';
import LeaguesStyle from '../components/styles/LeaguesStyle.css';
const Leagues = () => {
const [teamz, setTeams] = useState([]);
const [loading, setLoading] = useState(false)
const [isOpen, setOpen] = useState(false);
const getTeams = async () => {
try {
const res = await axios.get('https://api-football-standings.azharimm.site/leagues');
setTeams(res.data.data)
setLoading(true);
console.log(res.data)
} catch (err) {
alert(err.message)
}
}
useEffect(() => {
getTeams();
}, []);
return (
<div className="leagues">
{loading &&
teamz.map(item => (
<div className='teamCard' key={item.id}>
<div onClick={() => setOpen(!isOpen)} className="teamDiv">
<img src={item.logos.dark} className='teamLogo' />
<h1>{item.name}</h1>
</div>
{isOpen && <div className='card-content-active'>{item.abbr}</div>}
</div>
))}
</div>
);
}
You need to track the individual truthy values per item.id. This can be easily done by using an object to keep track of all the previous states via the spread operator. Once an initial state is set per tab, then it's just a matter of toggling that individual state between true and false. You delineate between tabs by dynamically assigning the id to the truthy value ([id]: !isOpen[id]). Here is the code in totality:
import React, { useEffect, useState } from "react";
import axios from "axios";
import LeaguesStyle from "./LeaguesStyle.css";
const Leagues = () => {
const [teamz, setTeams] = useState([]);
const [loading, setLoading] = useState(false);
const [isOpen, setOpen] = useState({});
const getTeams = async () => {
try {
const res = await axios.get(
"https://api-football-standings.azharimm.site/leagues"
);
setTeams(res.data.data);
setLoading(true);
console.log(res.data);
} catch (err) {
alert(err.message);
}
};
useEffect(() => {
getTeams();
}, []);
const handleOpen = (id) => {
setOpen((prevTruthys) => ({ ...prevTruthys, [id]: !isOpen[id] }));
};
console.log(isOpen);
return (
<div className="leagues">
{loading &&
teamz.map((item) => (
<div className="teamCard" key={item.id}>
<div onClick={() => handleOpen(item.id)} className="teamDiv">
<img src={item.logos.dark} className="teamLogo" alt="logo" />
<h1>{item.name}</h1>
</div>
{isOpen[item.id] === true && (
<div className="card-content-active">{item.abbr}</div>
)}
</div>
))}
</div>
);
};
export default Leagues;
Here is the code sandbox: https://codesandbox.io/s/orrigenda-react-question-forked-42lbfo?file=/src/App.js
The solution is to store all clicked tabs in a list using the item ID, when the tab is open and you clicked again the ID is removed from the list
here is the code with the solution:
I created a function to update the state. setOpenById(tabId) and a function for checking if the tab is open isTabOpen(tabId)
the onClick now uses that function onClick={() => setOpenById(item.id)}
import React, { useEffect, useState } from "react";
import axios from "axios";
import LeaguesStyle from "./LeaguesStyle.css";
const Leagues = () => {
const [teamz, setTeams] = useState([]);
const [loading, setLoading] = useState(false);
const [openTab, setOpenTab] = useState([])
const getTeams = async () => {
try {
const res = await axios.get(
"https://api-football-standings.azharimm.site/leagues"
);
setTeams(res.data.data);
setLoading(true);
//console.log(res.data);
} catch (err) {
alert(err.message);
}
};
useEffect(() => {
getTeams();
}, []);
const setOpenById = (tabId) => {
if(!isTabOpen(tabId)){
setOpenTab([...openTab, tabId])
} else{
var array = [...openTab] // make a separate copy of the array
var index = array.indexOf(tabId)
if (index !== -1) {
array.splice(index, 1)
setOpenTab(array)
}
}
}
const isTabOpen = (tabId) => {
return openTab.indexOf(tabId) !== -1
}
return (
<div className="leagues">
{loading &&
teamz.map((item) => (
<div className="teamCard" key={item.id}>
<div onClick={() => setOpenById(item.id)} className="teamDiv">
<img src={item.logos.dark} className="teamLogo" alt="logo" />
<h1>{item.name}</h1>
</div>
{isTabOpen(item.id) && <div className="card-content-active">{item.abbr}</div>}
</div>
))}
</div>
);
};
export default Leagues;

How to pass data from child to parent and render content based on selected value in dropdown?

I am learning React as I am fetching data from Pokéapi to make a list component, card component, detail component and filter component. I am trying to make a filter so you can filter by pokémon type. Only the cards that also contain that type string should then render (Not there yet). So I am not sure if a) I should make a different call from API inside PokemonList depending on selected value or b) if I should compare the values and just change how the PokemonCard element is rendered inside PokemonList.js depending on the comparison. I managed to pass data from filter to the list component. I have then been trying to pass the type data from PokemonCard.js to the list component so that I can compare these two values but I find it hard to use callbacks to pass the type data from the card component, since I dont pass it through an event or something like that.
Which method should I use here to simplify the filtering? Make different API call or render PokemonCard element conditionally?
Is it a good idea to compare filter option to pokemon card's type in PokemonList.js? Then how can I pass that data from the card component since I don't pass it through click event?
Thankful for any ideas! I paste the code from list component that contains the cards, card component and filter component.
PokemonList component:
import { useState } from 'react';
import useSWR from 'swr';
import PokemonCard from './PokemonCard';
import PokemonFilter from './PokemonFilter';
import './PokemonList.css';
const PokemonList = () => {
const [index, setIndex] = useState(0);
const [type, setType] = useState('');
function selectedType(type) { // value from filter dropdown
setType(type)
console.log("handled")
console.log(type)
}
const url = `https://pokeapi.co/api/v2/pokemon?limit=9&offset=${index}`;
const fetcher = (...args) => fetch(...args).then((res) => res.json())
const { data: result, error } = useSWR(url, fetcher);
if (error) return <div>failed to load</div>
if (!result) return <div>loading...</div>
result.results.sort((a, b) => a.name < b.name ? -1 : 1);
return (
<section>
<PokemonFilter onSelectedType={selectedType} selectedPokemonType={type} />
<div className="pokemon-list">
<div className="pokemons">
{result.results.map((pokemon) => (
<PokemonCard key={pokemon.name} pokemon={pokemon} /> // callback needed??
))}
</div>
<div className="pagination">
<button
onClick={() => setIndex(index - 9)}
disabled={result.previous === null}
>
Previous
</button>
<button
onClick={() => setIndex(index + 9)}
disabled={result.next === null}
>
Next
</button>
</div>
</div>
</section>
)
}
export default PokemonList;
PokemonCard component:
import { Link } from "react-router-dom";
import useSWR from 'swr';
import './PokemonCard.css';
const PokemonCard = ({ pokemon }) => {
const { name } = pokemon;
const url = `https://pokeapi.co/api/v2/pokemon/${name}`;
const { data, error } = useSWR(url);
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
const { types, abilities } = data;
// types[0].type.name <---- value I want to pass to PokemonList.js
return (
<div className='pokemon-card'>
<div className='pokemon-card__content'>
<img
className='pokemon-card__image'
src={data.sprites.front_default}
alt={name}
/>
<div className='pokemon-card__info'>
<p className='pokemon-card__name'>Name: {name}</p>
<p className='pokemon-card__abilities'>Abilities: {abilities[0].ability.name}</p>
<p className='pokemon-card__categories'>Category: {types[0].type.name}</p>
</div>
</div>
<Link className='pokemon-card__link' to={{
pathname: `/${name}`,
state: data
}}>
View Details
</Link>
</div>
)
}
export default PokemonCard;
PokemonFilter component:
import './PokemonFilter.css';
import useSWR from 'swr';
const PokemonFilter = ({onSelectedType, selectedPokemonType}) => {
const url = `https://pokeapi.co/api/v2/type/`;
const fetcher = (...args) => fetch(...args).then((res) => res.json())
const { data: result, error } = useSWR(url, fetcher);
if (error) return <div>failed to load</div>
if (!result) return <div>loading...</div>
function filteredTypeHandler(e) {
console.log(e.target.value);
onSelectedType(e.target.value);
}
console.log(selectedPokemonType)
return(
<div className="pokemon-types__sidebar">
<h2>Filter Pokémon by type</h2>
<select
name="pokemon-type"
className="pokemon-types__filter"
onChange={filteredTypeHandler}
>
<option value="All">Filter By Type</option>
{result.results.map((type) => {
return (
<option key={type.name} value={type.name}> {type.name}</option>
)
})}
</select>
</div>
)
}
export default PokemonFilter;
Here is an example to improve, modify, ... I didn't test, it's just a visual example.
I don't know about useSWR sorry, I use axios in my example...
If you want to centralize all your API requests, you can create a useApi hook, on the internet you will find tutorials.
PokemonList.js
import React, { useState, useEffect } from 'react';
import axios from 'axios'; // or swr
import PokemonFilter from './PokemonFilter';
import PokemonCard from './PokemonCard';
export default function PokemonList() {
const [data, setData] = useState([]);
const [filter, setFilter] = useState('');
// Executed every first render
useEffect(() => {
getData();
}, []);
// Executed only when filter changes
useEffect(() => {
getDataByTypes(filter);
}, [filter]);
// Get data
const getData = async () => {
const uri = 'https://xxx';
try {
const response = await axios.get(uri);
setData(response.data...);
} catch (error) {
console.log(error);
}
};
// Get data by types
const getDataByTypes = async (filter) => {
const uri = `https://xxx/type/${filter}...`;
if (filter) {
try {
const response = await axios.get(uri);
setData(response.data...);
} catch (error) {
console.log(error);
}
}
};
return (
<div className="main">
<PokemonFilter filter={filter} setFilter={setFilter} />
<div className="container">
<div className="cards-container">
{data.map((d) => (
<PokemonCard key={d.name} data={d} />
))}
</div>
</div>
</div>
);
}
PokemonCard.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export default function PokemonCard({ data }) {
const [pokemons, setPokemons] = useState();
useEffect(() => {
getPokemons(data);
}, [data]);
// Get Pokemons
const getPokemons = async (data) => {
const uri = `https://xxx/pokemon/${data.name}/`;
try {
const response = await axios.get(uri);
setPokemons(response.data...);
} catch (error) {
console.log(error);
}
};
return (
<div>
{pokemons && (
<div className="card">
<img src={pokemons.sprites.front_default} alt={pokemons.name} />
<p>{pokemons.name}</p>
<p>{pokemons.abilities[0].ability.name}</p>
<p>{pokemons.types[0].type.name}</p>
</div>
)}
</div>
);
}
PokemonFilter.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export default function PokemonFilter({ filter, setFilter }) {
const [types, setTypes] = useState([]);
useEffect(() => {
getType();
}, []);
// Get Type
const getType = async () => {
const uri = 'https://xxx/type/';
try {
const response = await axios.get(uri);
setTypes(response.data.results....);
} catch (error) {
console.log(error);
}
};
const handleFilter = (e) => {
setFilter(e.target.value);
};
return (
<select onChange={handleFilter} value={filter}>
<option>Filter by type</option>
{types.map((type) => {
return (
<option key={type.name} value={type.name}>
{type.name}
</option>
);
})}
</select>
);
}

try to end up search filter with react but there is mistake

This is my main component for seraching:
import React, {useState, useEffect} from 'react';
import SearchBar from "./SearchBar";
import SearchList from "./SongList";
const SearchMusic = (props) => {
const [input, setInput] = useState('');
const [songListDefault, setSongListDefault] = useState();
const [songList, setSongList] = useState();
const fetchData = async () => {
return await fetch('http://ws.audioscrobbler.com/2.0/?method=tag.gettoptracks&tag=disco&api_key=c17b1886d9465542a9cd32437c804db6&format=json')
.then(response => response.json())
.then(data => {
setSongList(data)
setSongListDefault(data)
});
}
const updateInput = async (input) => {
const filtered = songListDefault.filter(song => {
return song.name.toLowerCase().includes(input.toLowerCase())
})
setInput(input);
setSongList(filtered);
}
useEffect(() => {
fetchData()
}, [])
return (
<div>
<h1>Song List</h1>
<SearchBar
input={input}
onChange={updateInput}
/>
<SearchList songList={songList}/>
</div>
);
};
export default SearchMusic;
below is separate input js file:
import React from 'react';
const SearchMusic = ({keyword, setKeyword}) => {
const BarStyling = {width: "20rem", background: "#F2F1F9", border: "none", padding: "0.5rem"};
return (
<input
type="text"
style={BarStyling}
key='random1'
value={keyword}
placeholder={'Search a song'}
onChange={(e => setKeyword(e.target.value))}
/>
);
};
export default SearchMusic;
end it is my song list below:
import React from 'react';
const SongList = ({songList = []}) => {
return (
<div>
{
songList && songList.tracks.track.map((song, index) => {
if (song) {
return (
<div key={song.name}>
<h1>{song.name}</h1>
</div>
)
}
return null;
}
)
}
</div>
);
};
export default SongList;
I get this mistake --> TypeError: setKeyword is not a function. I don't what's wrong and don't know how to get rid of it. It seems to me problem is in updateInput function more precisely in what it returns --> song.name.toLowerCase(). There is api link:
http://ws.audioscrobbler.com/2.0/?method=tag.gettoptracks&tag=disco&api_key=c17b1886d9465542a9cd32437c804db6&format=json
I need to get name of a song in search input... But something's wrong
The props that this component are expecting are not getting passed into component in your parent component
const SearchMusic = ({keyword, setKeyword}) => {
const BarStyling = {width: "20rem", background: "#F2F1F9", border: "none", padding: "0.5rem"};
return (
<input
type="text"
style={BarStyling}
key='random1'
value={keyword}
placeholder={'Search a song'}
onChange={(e => setKeyword(e.target.value))}
/>
);
};
That is assuming that the following is the above component
<SearchBar
input={input}
onChange={updateInput}
/>
How about
<SearchBar
keyword={input}
setKeyword={updateInput}
/>

How make work a search filter in react for node array

Hi guys i make a search filter in react for an array i get via my node server, but i got this error:
×
TypeError: props.filteredCharacters.map is not a function in components/CharacterList/index.js:6
Here the 2 files:
import React, { useEffect, useState } from 'react'
import SearchBox from '../SearchBox'
import CharacterList from '../CharacterList'
const SearchDisney = () => {
const [inputs, setInputs] = useState('');
const [btn, setBtn] = useState(false);
const [apiResponse, setApiResponse] = useState([]);
const [searchCharacter, setSearchCharacter] = useState('');
useEffect(() => {
callAPI();
if (inputs.length > 2) {
setBtn(true)
} else if (btn) {
setBtn(false)
}
}, [inputs, btn])
const callAPI = () => {
fetch("http://localhost:9000/disneyCharacter")
.then(res => res.json())
.then(res => setApiResponse(res))
}
const handleInput = (e) => {
setSearchCharacter(e.target.value)
}
const filteredCharacters = () => {
apiResponse.filter((character) => {
return character.name.toLowerCase().includes(searchCharacter.toLowerCase())
})
}
return (
<div className="search-container">
<h1>Personnage Infos</h1>
<SearchBox handleInput={handleInput} />
<CharacterList filteredCharacters={filteredCharacters} />
</div>
)
}
export default React.memo(SearchDisney)
And the CharacterList:
import React from 'react'
import Character from '../Character'
const CharacterList = (props) => {
const characters = props.filteredCharacters.map((character, id) => {
return <Character key={id} name={character.name} username={character.username} yearCreation={character.yearCreation}/>
})
return (
<div>
{ characters }
</div>
)
}
export default CharacterList
i can display the array in the first file but now i want to make search filter and got this error, any advice to get ride of this error?
Looks like there are 2 things you need to fix here:
on the SearchDisney component, you are not returning anything from the filteredCharacters function. Here is the fix:
const filteredCharacters = () => {
//need to return this
return apiResponse.filter((character) => {
return character.name.toLowerCase().includes(searchCharacter.toLowerCase())
})
}
Addtionally, in order for CharacterList to recieve the filteredCharacters prop as an array - you have to call the filteredCharacters function which returns this array, for example, like this:
<div className="search-container">
<h1>Personnage Infos</h1>
<SearchBox handleInput={handleInput} />
//call the function here:
<CharacterList filteredCharacters={filteredCharacters()} />
</div>

Categories

Resources