I am consuming the Rick and Morty API with react query and displaying the data in the Home component
The Home component has 3 children components, the Card to display the data, a search feature and a pagination feature
My question is: Can i move the logic (state, function and variables) related to the children component into another file? Is it good practice to do this? I am new to React and trying to understand design patterns. Any sugestion about the folder structure to this pattern is welcomed...
I developed the following code, but i wanted to be more modularized and cleaner...
import React, { useState } from 'react';
import { useCharacters } from './service/api';
import Cardi from './styles/blocks/Cardi';
import Pagination from './styles/blocks/Pagination';
import SearchInput from './styles/blocks/Search';
const Home = () => {
const { data, isLoading, isError } = useCharacters(); //API Data
const [currentPage, setCurrentPage] = useState(1); // State da página atual
const [searchQuery, setSearchQuery] = useState(''); // State da barra de pesquisa
const itemsPerPage = 9
console.log('home' + data)
if (isLoading) {
return <div>Loading...</div>;
}
if (isError) {
return <div>Error fetching data</div>;
}
//Set o state da barra de busca e set a página inicial para 1 para mostrar os resultados na primeira página
const handleSearch = (event) => {
setSearchQuery(event.target.value);
setCurrentPage(1); // Reset to the first page when searching
};
// Filter the data based on the search query
const filteredData = data.filter((item) =>
item.name.toLowerCase().includes(searchQuery.toLowerCase())
);
// Calculate the range of items to display based on the current page
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const currentItems = filteredData.slice(startIndex, endIndex);
const totalPages = Math.ceil(filteredData.length / itemsPerPage);
const handlePageChange = (page) => {
setCurrentPage(page);
};
return (
<div>
<SearchInput value={searchQuery} onChange={handleSearch} />
<Cardi.Grid>
{currentItems.map((item) => (
<Cardi key={item.id}>
<Cardi.Image src={item.image}/>
<Cardi.Title>{item.name}</Cardi.Title>
<Cardi.Specs>{item.species}</Cardi.Specs>
<Cardi.Specs>{item.status}</Cardi.Specs>
<Cardi.Button to={`/details/${item.id}`}></Cardi.Button>
</Cardi>
))}
</Cardi.Grid>
<Pagination
totalPages={totalPages}
currentPage={currentPage}
onPageChange={handlePageChange}
/>
</div>
);
};
export default Home;
You can create a custom hook and move state, function in it, From the custom hook you can export state, function
One more suggestion, You can create a separate component for Cardi Items and move all logic related to list items into that component.
return (
<div>
<SearchInput value={searchQuery} onChange={handleSearch} />
<Cardi.Grid>
{currentItems.map((item) => (
<CardiList item={item}/>
))}
</Cardi.Grid>
<Pagination
totalPages={totalPages}
currentPage={currentPage}
onPageChange={handlePageChange}
/>
</div>
);