我有此复选框输入,当我单击它时,我将其取值并添加到名为vendorFilters的状态数组中,但似乎状态总是落后了1步,我在使用类组件,我认为切换到挂钩可能会解决问题但是没有。
我附上了codesandbox链接,请看一下。
https://codesandbox.io/s/naughty-brattain-89hxi?file=/src/App.js
import React, { useState, useEffect } from "react";
import "./styles.css";
import raw from "./data.json";
const App = () => {
const [data, setData] = useState([]);
const [vendorFilters, setVendorFilters] = useState([]);
const [capacityFilters, setCapacityFilters] = useState([]);
const [speedFilters, setSpeedFilters] = useState([]);
const [cycleLatencyFilters, setCycleLatencyFilters] = useState([]);
const [colorFilters, setColorFilters] = useState([]);
const [vendorQuantity, setVendorQuantity] = useState([0, 0, 0, 0, 0, 0]);
useEffect(() => setData(raw), []);
const inputHandler = event => {
updateFiltersArrays(
event.target.value,
event.target.name,
event.target.checked
);
console.log(vendorFilters);
filterFunction();
};
const filterFunction = () => {
const filteredData1 = data.filter(object => {
if (vendorFilters.length === 0) return true;
return vendorFilters.includes(object.vendor);
});
const filteredData2 = filteredData1.filter(({ capacity }) => {
if (capacityFilters.length === 0) return true;
return capacityFilters.includes(capacity.toString());
});
const filteredData3 = filteredData2.filter(({ speed }) => {
if (speedFilters.length === 0) return true;
return speedFilters.includes(speed.toString());
});
const filteredData4 = filteredData3.filter(({ cycleLatency }) => {
if (cycleLatencyFilters.length === 0) return true;
return cycleLatencyFilters.includes(cycleLatency.toString());
});
const filteredData5 = filteredData4.filter(({ color }) => {
if (colorFilters.length === 0) return true;
return colorFilters.includes(color.toString());
});
console.log("hikhan");
const vendor = [0, 0, 0, 0, 0, 0];
vendor[0] = filteredData5.filter(
object => object.vendor === "BESTRAM" && vendorFilters.includes("BESTRAM")
).length;
};
const updateFiltersArrays = (input, collection, checked) => {
switch (collection) {
case "vendor":
if (checked) {
setVendorFilters([...vendorFilters, input]);
} else {
const filters = vendorFilters.filter(f => f !== input);
setVendorFilters(filters);
}
break;
case "capacity":
if (checked) {
setCapacityFilters(prev => [...prev, input]);
} else {
const filters = vendorFilters.filter(f => f !== input);
setCapacityFilters(filters);
}
break;
case "speed":
if (checked) {
setSpeedFilters(prev => [...prev, input]);
} else {
const filters = vendorFilters.filter(f => f !== input);
setSpeedFilters(filters);
}
break;
case "cycleLatency":
if (checked) {
setCycleLatencyFilters(prev => [...prev, input]);
} else {
const filters = vendorFilters.filter(f => f !== input);
setCycleLatencyFilters(filters);
}
break;
case "color":
if (checked) {
setColorFilters(prev => [...prev, input]);
} else {
const filters = vendorFilters.filter(f => f !== input);
setColorFilters(filters);
}
break;
default:
break;
}
};
return (
<div class="main-content">
<h1>Filter Predictions</h1>
<div class="filter">
<div class="group" data-test="vendor-group">
<div class="group__name">vendor</div>
<label class="group__item" data-test="item-BESTRAM">
<input
type="checkbox"
value="BESTRAM"
name="vendor"
onClick={inputHandler}
/>
BESTRAM ({vendorQuantity[0]})
</label>
<label class="group__item" data-test="item-Rocket">
<input
type="checkbox"
value="Rocket"
name="vendor"
onClick={inputHandler}
/>
Rocket ()
</label>
<label class="group__item" data-test="item-gTech">
<input
type="checkbox"
value="gTech"
name="vendor"
onClick={inputHandler}
/>
gTech ({vendorQuantity[2]})
</label>
<label class="group__item" data-test="item-5Byte">
<input
type="checkbox"
value="5Byte"
name="vendor"
onClick={inputHandler}
/>
5Byte ({vendorQuantity[3]})
</label>
<label class="group__item" data-test="item-Xdata">
<input
type="checkbox"
value="Xdata"
name="vendor"
onClick={inputHandler}
/>
Xdata ({vendorQuantity[4]})
</label>
<label class="group__item" data-test="item-Abc">
<input
type="checkbox"
value="Abc"
name="vendor"
onClick={inputHandler}
/>
Abc ({vendorQuantity[5]})
</label>
</div>
<div class="group" data-test="capacity-group">
<div class="group__name">capacity</div>
<label class="group__item" data-test="item-4">
<input
type="checkbox"
value={4}
name="capacity"
onClick={inputHandler}
/>
4 GB ()
</label>
<label class="group__item" data-test="item-8">
<input
type="checkbox"
value={8}
name="capacity"
onClick={inputHandler}
/>
8 GB ()
</label>
<label class="group__item" data-test="item-32">
<input
type="checkbox"
value={32}
name="capacity"
onClick={inputHandler}
/>
32 GB ()
</label>
<label class="group__item" data-test="item-16">
<input
type="checkbox"
value={16}
name="capacity"
onClick={inputHandler}
/>
16 GB ()
</label>
</div>
<div class="group" data-test="speed-group">
<div class="group__name">speed</div>
<label class="group__item" data-test="item-2400">
<input
type="checkbox"
value={2400}
name="speed"
onClick={inputHandler}
/>
2400 MHz (80)
</label>
<label class="group__item" data-test="item-2666">
<input
type="checkbox"
value={2666}
name="speed"
onClick={inputHandler}
/>
2666 MHz (30)
</label>
<label class="group__item" data-test="item-3333">
<input
type="checkbox"
value={3333}
name="speed"
onClick={inputHandler}
/>
3333 MHz (25)
</label>
<label class="group__item" data-test="item-3200">
<input
type="checkbox"
value={3200}
name="speed"
onClick={inputHandler}
/>
3200 MHz (23)
</label>
<label class="group__item" data-test="item-3600">
<input
type="checkbox"
value={3600}
name="speed"
onClick={inputHandler}
/>
3600 MHz (21)
</label>
<label class="group__item" data-test="item-4000">
<input
type="checkbox"
value={4000}
name="speed"
onClick={inputHandler}
/>
4000 MHz (21)
</label>
</div>
<div class="group" data-test="cycle-latency-group">
<div class="group__name">cycle latency</div>
<label class="group__item" data-test="item-CL-7">
<input
type="checkbox"
value={"CL 7"}
name="cycleLatency"
onClick={inputHandler}
/>
CL 7 (54)
</label>
<label class="group__item" data-test="item-CL-9">
<input
type="checkbox"
value={"CL 9"}
name="cycleLatency"
onClick={inputHandler}
/>
CL 9 (51)
</label>
<label class="group__item" data-test="item-CL-12">
<input
type="checkbox"
value={"CL 12"}
name="cycleLatency"
onClick={inputHandler}
/>
CL 12 (51)
</label>
<label class="group__item" data-test="item-CL-11">
<input
type="checkbox"
value={"CL 11"}
name="cycleLatency"
onClick={inputHandler}
/>
CL 11 (44)
</label>
</div>
<div class="group" data-test="color-group">
<div class="group__name">color</div>
<label class="group__item" data-test="item-Green">
<input
type="checkbox"
value={"Green"}
name="color"
onClick={inputHandler}
/>
Green (94)
</label>
<label class="group__item" data-test="item-Black">
<input
type="checkbox"
value={"Black"}
name="color"
onClick={inputHandler}
/>
Black (50)
</label>
<label class="group__item" data-test="item-Red">
<input
type="checkbox"
value={"Red"}
name="color"
onClick={inputHandler}
/>
Red (31)
</label>
<label class="group__item" data-test="item-White">
<input
type="checkbox"
value={"White"}
name="color"
onClick={inputHandler}
/>
White (25)
</label>
</div>
</div>
</div>
);
};
export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
答案 0 :(得分:0)
setState是一个异步函数,它需要一些时间来更新状态。它不是瞬时的。这是因为setState更改状态并导致重新呈现。这可能是一项昂贵的操作,并且使其同步可能会使浏览器无响应。因此,setState调用是异步的,也可以是批处理的,以便获得更好的UI体验和性能。
幸运的是,setState进行了回调:
this.setState({ param: "param" }, () => {
//callback
console.log(this.state.param) // your param
});
答案 1 :(得分:0)
setState是一个异步函数,因此array的值可能尚未更新。在下一个渲染周期中它将具有更新的值。
解决方案是使用useEffect
react hook
const inputHandler = event => {
updateFiltersArrays(
event.target.value,
event.target.name,
event.target.checked
);
// remove function call from here
};
const filterFunction = useCallback(()=>{
// rest of the code
},[])
useEffect(()=>{
console.log(vendorFilters); // will have updated value
filterFunction()
},[vendorFilters,filterFunction])
以上代码指出,vendorFilter
发生更改时,请运行此功能