React.JS react query 设计模式

huangapple go评论83阅读模式
英文:

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 &#39;react&#39;;
import { useCharacters } from &#39;./service/api&#39;;
import Cardi from &#39;./styles/blocks/Cardi&#39;;
import Pagination from &#39;./styles/blocks/Pagination&#39;;
import SearchInput from &#39;./styles/blocks/Search&#39;;
const Home = () =&gt; {
const { data, isLoading, isError } = useCharacters(); //API Data
const [currentPage, setCurrentPage] = useState(1); // State da p&#225;gina atual
const [searchQuery, setSearchQuery] = useState(&#39;&#39;); // State da barra de pesquisa
const itemsPerPage = 9
console.log(&#39;home&#39; + data)
if (isLoading) {
return &lt;div&gt;Loading...&lt;/div&gt;;
}
if (isError) {
return &lt;div&gt;Error fetching data&lt;/div&gt;;
}
//Set o state da barra de busca e set a p&#225;gina inicial para 1 para mostrar os resultados na primeira p&#225;gina
const handleSearch = (event) =&gt; {
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) =&gt;
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) =&gt; {
setCurrentPage(page);
};
return (
&lt;div&gt;
&lt;SearchInput value={searchQuery} onChange={handleSearch} /&gt;
&lt;Cardi.Grid&gt;
{currentItems.map((item) =&gt; (
&lt;Cardi key={item.id}&gt;
&lt;Cardi.Image src={item.image}/&gt; 
&lt;Cardi.Title&gt;{item.name}&lt;/Cardi.Title&gt;
&lt;Cardi.Specs&gt;{item.species}&lt;/Cardi.Specs&gt;
&lt;Cardi.Specs&gt;{item.status}&lt;/Cardi.Specs&gt;
&lt;Cardi.Button to={`/details/${item.id}`}&gt;&lt;/Cardi.Button&gt;
&lt;/Cardi&gt;
))}
&lt;/Cardi.Grid&gt;
&lt;Pagination
totalPages={totalPages}
currentPage={currentPage}
onPageChange={handlePageChange}
/&gt;
&lt;/div&gt;
);
};
export default Home;

答案1

得分: 0

你可以创建一个自定义钩子,并将状态,函数放入其中,
从自定义钩子中可以导出状态,函数

再提一个建议,你可以为卡片项创建一个单独的组件,并将所有与列表项相关的逻辑移动到该组件中。

    return (
&lt;div&gt;
&lt;SearchInput value={searchQuery} onChange={handleSearch} /&gt;
&lt;Cardi.Grid&gt;
{currentItems.map((item) =&gt; (
&lt;CardiList item={item}/&gt;
))}
&lt;/Cardi.Grid&gt;
&lt;Pagination
totalPages={totalPages}
currentPage={currentPage}
onPageChange={handlePageChange}
/&gt;
&lt;/div&gt;
);
英文:

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 (
&lt;div&gt;
&lt;SearchInput value={searchQuery} onChange={handleSearch} /&gt;
&lt;Cardi.Grid&gt;
{currentItems.map((item) =&gt; (
&lt;CardiList item={item}/&gt;
))}
&lt;/Cardi.Grid&gt;
&lt;Pagination
totalPages={totalPages}
currentPage={currentPage}
onPageChange={handlePageChange}
/&gt;
&lt;/div&gt;
);

huangapple
  • 本文由 发表于 2023年7月3日 19:46:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76604425.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定