如何在React中的排序方法中触发渲染(带有筛选和分页)?

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

How to trigger render on sort method in React (with filter and pagination)?

问题

这是我的Sort.js样式组件:

<SortWrapper>
  <SortText>按以下方式排序</SortText>
  <SortSelect onChange={onSelectChange}>
    <SortOption value="vehicleMake">车辆品牌</SortOption>
    <SortOption value="vehicleModel">车辆型号</SortOption>
  </SortSelect>
</SortWrapper>

这是在App.js中渲染Sort组件的函数:

<Sort onSelectChange={onSelectChange} />

这是一个函数:

const onSelectChange = (e) => {
  const value = e.target.value;

  if (value === "vehicleMake")
    vehicles.sort((a, b) => a.vehicleMake.localeCompare(b.vehicleMake));
  else if (value === "vehicleModel") {
    vehicles.sort((a, b) => a.vehicleModel.localeCompare(b.vehicleModel));
  } else {
    vehicles.sort((a, b) => a.id - b.id);
  }
}

"vehicles"是我从Firestore数据库获取的对象数组

每当我更改SortOption的值时它不会自动排序我的对象数组但当我点击分页的第2页然后再点击第1页时它会排序

这是我的Grid组件

```jsx
<Grid>
  {vehiclesData.map((vehicle) => (
    <VehicleCard
      id={vehicle.id}
      key={vehicle.id}
      ImageURL={vehicle.ImageURL}
      vehicleMake={vehicle.vehicleMake}
      vehicleModel={vehicle.vehicleModel}
      selectVehicle={() => setSelectedVehicle(vehicle)}
      deleteHandler={() => deleteHandler(vehicle.id)}
    />
  ))}
</Grid>

这是我的过滤函数:

const vehiclesData = useMemo(() => {
  let computedVehicles = vehicles;

  if (searchVehicle) {
    computedVehicles = computedVehicles.filter((vehicle) =>
      vehicle.vehicleMake.toLowerCase().includes(searchVehicle.toLowerCase())
    );
  }

  setTotalVehicles(computedVehicles.length);

  return computedVehicles.slice(
    (currentPage - 1) * vehiclesPerPage,
    (currentPage - 1) * vehiclesPerPage + vehiclesPerPage
  );
}

正如我之前所写,我希望我的车辆根据制造商或型号自动渲染,而不是在分页中单击页面号时才排序。

英文:

This is my Sort.js styled component:

   &lt;SortWrapper&gt;
    &lt;SortText&gt;Sort By&lt;/SortText&gt;
    &lt;SortSelect onChange={onSelectChange}&gt;
      &lt;SortOption value=&quot;vehicleMake&quot;&gt;Vehicle make&lt;/SortOption&gt;
      &lt;SortOption value=&quot;vehicleModel&quot;&gt;Vehicle model&lt;/SortOption&gt;
    &lt;/SortSelect&gt;
  &lt;/SortWrapper&gt;

This is function in App.js, where Sort component is rendered

&lt;Sort onSelectChange={onSelectChange} /&gt;

This is a function:

  const onSelectChange = (e) =&gt; {
const value = e.target.value;

if (value === &quot;VehicleMake&quot;)
  vehicles.sort((a, b) =&gt; a.vehicleMake.localeCompare(b.vehicleMake));
else if (value === &quot;VehicleModel&quot;) {
  vehicles.sort((a, b) =&gt; a.vehicleModel.localeCompare(b.vehicleModel));
} else {
  vehicles.sort((a, b) =&gt; a.id - b.id);
}

"vehicles" are a array of objects that I am getting from Firestore Database.

Whenever I change value of SortOption it does not sort my array of objects automatically, BUT it sorts it when I click page 2, and then page 1 in my pagination.

This is my Grid component:

       &lt;Grid&gt;
      {vehiclesData.map((vehicle) =&gt; (
        &lt;VehicleCard
          id={vehicle.id}
          key={vehicle.id}
          ImageURL={vehicle.ImageURL}
          vehicleMake={vehicle.vehicleMake}
          vehicleModel={vehicle.vehicleModel}
          selectVehicle={() =&gt; setSelectedVehicle(vehicle)}
          deleteHandler={() =&gt; deleteHandler(vehicle.id)}
        /&gt;
      ))}
    &lt;/Grid&gt;

This is my filter function:

const vehiclesData = useMemo(() =&gt; {
let computedVehicles = vehicles;

if (searchVehicle) {
  computedVehicles = computedVehicles.filter((vehicle) =&gt;
    vehicle.vehicleMake.toLowerCase().includes(searchVehicle.toLowerCase())
  );
}

setTotalVehicles(computedVehicles.length);

return computedVehicles.slice(
  (currentPage - 1) * vehiclesPerPage,
  (currentPage - 1) * vehiclesPerPage + vehiclesPerPage
);

As I wrote before, I want my vehicles to render by make or model automatically, not when I click on page number in pagination.

答案1

得分: 0

你的排序方法应该看起来像这样:

const onSelectChange = (e) => {
  let temVehicles = [...vehicles];
  const value = e.target.value;

  if (value === "VehicleMake")
    temVehicles.sort((a, b) => a.vehicleMake.localeCompare(b.vehicleMake));
  else if (value === "VehicleModel") {
    temVehicles.sort((a, b) => a.vehicleModel.localeCompare(b.vehicleModel));
  } else {
    temVehicles.sort((a, b) => a.id - b.id);
  }
  setVehicles(temVehicles);
}

而你的过滤函数应该如下所示:

const vehiclesData = useMemo(() => {
  let computedVehicles = vehicles;

  if (searchVehicle) {
    computedVehicles = computedVehicles.filter((vehicle) =>
      vehicle.vehicleMake.toLowerCase().includes(searchVehicle.toLowerCase())
    );
  }

  setTotalVehicles(computedVehicles.length);

  return computedVehicles.slice(
    (currentPage - 1) * vehiclesPerPage,
    (currentPage - 1) * vehiclesPerPage + vehiclesPerPage
  );
}, [vehicles]);

基本上,一旦 onSelectChange 运行,你会更新你的 vehicles 状态,然后 useMemo 应该再次运行,因此我们将 vehicles 添加为它的依赖项。

英文:

Your sort method should look something like this

 const onSelectChange = (e) =&gt; {
let temVehicles = [...vehicles]
const value = e.target.value;

if (value === &quot;VehicleMake&quot;)
  temVehicles .sort((a, b) =&gt; a.vehicleMake.localeCompare(b.vehicleMake));
else if (value === &quot;VehicleModel&quot;) {
  temVehicles .sort((a, b) =&gt; a.vehicleModel.localeCompare(b.vehicleModel));
} else {
  temVehicles .sort((a, b) =&gt; a.id - b.id);
}
setVehicles(temVehicles )}

And your filter function should look like this

const vehiclesData = useMemo(() =&gt; {
let computedVehicles = vehicles;

if (searchVehicle) {
  computedVehicles = computedVehicles.filter((vehicle) =&gt;
    vehicle.vehicleMake.toLowerCase().includes(searchVehicle.toLowerCase())
  );
}

setTotalVehicles(computedVehicles.length);

return computedVehicles.slice(
  (currentPage - 1) * vehiclesPerPage,
  (currentPage - 1) * vehiclesPerPage + vehiclesPerPage
);},[vehicles])

Basically once onSelectChange runs, you update your vehicles state and then the usememo should run again and thus we add dependency vehicles to it

huangapple
  • 本文由 发表于 2023年6月26日 14:53:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76554186.html
匿名

发表评论

匿名网友

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

确定