英文:
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:
<SortWrapper>
<SortText>Sort By</SortText>
<SortSelect onChange={onSelectChange}>
<SortOption value="vehicleMake">Vehicle make</SortOption>
<SortOption value="vehicleModel">Vehicle model</SortOption>
</SortSelect>
</SortWrapper>
This is function in App.js, where Sort component is rendered
<Sort onSelectChange={onSelectChange} />
This is a function:
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" 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:
<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>
This is my filter function:
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
);
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) => {
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 )}
And your filter function should look like this
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])
Basically once onSelectChange runs, you update your vehicles state and then the usememo should run again and thus we add dependency vehicles to it
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论