更新基于 Jayce444 的评论。我将计时器设置在组件之外,这很有帮助。全局变量是最好的主意吗?
let globalTimer = null;
const setSlidingTimer = (timer) => {
globalTimer = timer;
};
const SearchJobs = (props) => {
useEffect(() => console.log("<SearchJobs /> rendered"));
const [sliderValue, setSliderValue] = useState(20);
const sliderChangeHandler = (newValue) => {
clearTimeout(globalTimer);
const timer = setTimeout(setSliderValue, 300, newValue);
setSlidingTimer(timer);
};
原帖:
我的 React 应用程序由于父组件的过多重新渲染而导致性能下降,因为它的子组件(主要是滑块)在更改其值时过于频繁地更改状态。
我的想法(参见sliderChangeHandler)是在更新滑块的状态值之前等待300毫秒以减少重新渲染的数量。不知何故,这还行不通。有没有人可以帮助我特别是滑块并将类似的想法应用于输入框?就像在更新状态之前等待 300 毫秒一样。如果用户再次键入或滑动,请重置 300ms 计时器。
这是父代码
import React, { useEffect, useState } from "react";
import Col from "react-bootstrap/Col";
import Button from "react-bootstrap/Button";
import InputGroup from "react-bootstrap/InputGroup";
import FormControl from "react-bootstrap/FormControl";
import Slider from "../UI/Slider/Slider";
const SearchJobs = (props) => {
useEffect(() => console.log("<SearchJobs /> rendered"));
const [sliderValue, setSliderValue] = useState(20);
const [address, setAddress] = useState("");
const [slidingTimeout, setSlidingTimeout] = useState("");
const sliderChangeHandler = (event, newValue) => {
clearTimeout(slidingTimeout);
const timer = setTimeout(setSliderValue, 300, newValue);
setSlidingTimeout(timer);
};
return (
<>
<Col xs={12} md={7}>
<InputGroup className="mb-3">
<InputGroup.Prepend>
<InputGroup.Text id="inputGroup-sizing-default">
Adresse
</InputGroup.Text>
</InputGroup.Prepend>
<FormControl
aria-label="Address"
aria-describedby="inputGroup-sizing-default"
placeholder="myAddress"
value={address}
onChange={(event) => setAddress(event.target.value)}
/>
</InputGroup>
</Col>
<Col xs={12} md={5}>
<Slider value={sliderValue} change={sliderChangeHandler} />
</Col>
</>
);
};
export default SearchJobs;
这是滑块组件:
import React from "react";
import Typography from "@material-ui/core/Typography";
import Slider from "@material-ui/core/Slider";
const SliderComponent = (props) => {
const marks = [
{
value: 0,
label: "0 km",
},
{
value: 50,
label: "50 km",
},
];
function valuetext(value) {
return `${value} km`;
}
return (
<div className="ml-3 mr-3">
<Typography id="discrete-slider-always" gutterBottom>
Radius
</Typography>
<Slider
defaultValue={20}
value={props.sliderValue}
onChange={(event, newValue) => props.change(event, newValue)}
getAriaValueText={valuetext}
aria-labelledby="discrete-slider-always"
step={0.1}
min={0}
max={50}
marks={marks}
valueLabelDisplay="on"
/>
</div>
);
};
export default SliderComponent;