英文:
React.JS react query design pattern
问题
我正在使用 React Query 消耗 Rick and Morty API 并在 Home 组件中显示数据。
Home 组件有 3 个子组件,Card 用于显示数据,一个搜索功能和一个分页功能。
我的问题是:我可以将与子组件相关的逻辑(状态、函数和变量)移动到另一个文件吗?这样做是良好的实践吗?我是 React 新手,正在尝试理解设计模式。欢迎对此模式的文件结构提出建议...
我开发了以下代码,但我希望它更模块化和清晰...
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); // 当前页的状态
const [searchQuery, setSearchQuery] = useState(''); // 搜索栏的状态
const itemsPerPage = 9;
console.log('home' + data);
if (isLoading) {
return <div>Loading...</div>;
}
if (isError) {
return <div>Error fetching data</div>;
}
// 设置搜索栏的状态并将当前页设置为1,以在第一页显示结果
const handleSearch = (event) => {
setSearchQuery(event.target.value);
setCurrentPage(1); // 搜索时重置为第一页
};
// 根据搜索查询过滤数据
const filteredData = data.filter((item) =>
item.name.toLowerCase().includes(searchQuery.toLowerCase())
);
// 根据当前页计算要显示的项目范围
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;
如您所需,您可以将子组件的相关逻辑移到单独的文件中,并在需要时导入它们,以使代码更模块化和清晰。
英文:
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;
答案1
得分: 0
你可以创建一个自定义钩子,并将状态,函数放入其中,
从自定义钩子中可以导出状态,函数
再提一个建议,你可以为卡片项创建一个单独的组件,并将所有与列表项相关的逻辑移动到该组件中。
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>
);
英文:
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>
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论