三元内部的函数导致无限循环
Function inside ternary causing infinite loop
不知道为什么,但是我的三元组中的一个函数导致了无限循环。
在 redux 中设置状态的 setUnit 函数导致页面无限循环/中断页面,我无法解释原因。函数修改了组件依赖的三元,所以可能是这个原因吧?
Current.js
const Current = () => {
const locationData = useSelector((state) => state.locationData);
const locationName = useSelector((state) => state.locationName.name);
const weatherData = useSelector((state) => state.weather.data);
const unit = useSelector((state) => state.units.unit);
const dispatch = useDispatch();
function setUnit(unit) {
if (unit === "metric") {
console.log("metric!");
dispatch(unitActions.setToMetric());
} else {
console.log("imperial!");
dispatch(unitActions.setToImperial());
}
}
return (
<div className="main-container">
<h2 className="location">{locationName}</h2>
<div className="top">
<img
src={`https://openweathermap.org/img/wn/${weatherData.current.weather[0].icon}@2x.png`}
alt="Weather icon"
className="weather-icon"
/>
<h1 className="temp">{Math.floor(weatherData.current.temp)}°</h1>
<div className="units-container">
{unit === "metric" ? (
<div>
<div className="unit" id="C">
<h2>C</h2>
</div>
<div
className="unit"
id="F"
onClick={setUnit("imperial")}
>
<h2>F</h2>
</div>
<div className="background"></div>
</div>
) : (
<div>
<div className="unit" id="F">
<h2>F</h2>
</div>
<div
className="unit"
id="C"
onClick={setUnit("metric")}
>
<h2>C</h2>
</div>
<div className="background"></div>
</div>
)}
</div>
</div>
<div className="bottom">
<h2 className="description">
{weatherData.current.weather[0].description[0].toUpperCase()}
{weatherData.current.weather[0].description.substring(1)}
</h2>
<h4 className="timestamp">
Updated as of {convertTime(weatherData.current.dt, "HH-MM")}
</h4>
<div className="bottom-icons">
<div className="icons" id="top-icons">
<div className="icon-element">
Feels like {weatherData.current.feels_like}°
</div>
<div className="icon-element" id="wind">
Wind {weatherData.current.wind_speed}km
</div>
<div className="icon-element" id="visibility">
Visibility {Math.round(weatherData.current.visibility / 1000)} km
</div>
</div>
<div className="icons">
<div className="icon-element">
Barometer {weatherData.current.pressure} mb
</div>
<div className="icon-element" id="humidity">
Humidity {weatherData.current.humidity}%;
</div>
<div className="icon-element" id="dew">
Dew Point {Math.round(weatherData.current.dew_point)}°
</div>
</div>
</div>
</div>
</div>
);
};
目前 setUnit
正在被立即调用,改变状态并使其持续 re-render。相反,将 setUnit
函数传递给 onClick
以仅在触发 onClick
事件时调用它:onClick={() => setUnit("imperial")}
.
另一种选择是将 setUnit
更改为 return 事件处理程序。这种方法的一个优点是 event
与效果 -
位于同一位置
const setUnit = (unit) => (event) => {
// access to `event` here
if (unit === "metric") {
console.log("metric!");
dispatch(unitActions.setToMetric());
} else {
console.log("imperial!");
dispatch(unitActions.setToImperial());
}
}
我喜欢这个选项,因为它使呼叫站点非常干净 -
<div
className="unit"
id="F"
onClick={setUnit("imperial")} {/* */}
children={<h2>F</h2>}
/>
相关:What do multiple arrow functions mean in JavaScript?
不知道为什么,但是我的三元组中的一个函数导致了无限循环。 在 redux 中设置状态的 setUnit 函数导致页面无限循环/中断页面,我无法解释原因。函数修改了组件依赖的三元,所以可能是这个原因吧?
Current.js
const Current = () => {
const locationData = useSelector((state) => state.locationData);
const locationName = useSelector((state) => state.locationName.name);
const weatherData = useSelector((state) => state.weather.data);
const unit = useSelector((state) => state.units.unit);
const dispatch = useDispatch();
function setUnit(unit) {
if (unit === "metric") {
console.log("metric!");
dispatch(unitActions.setToMetric());
} else {
console.log("imperial!");
dispatch(unitActions.setToImperial());
}
}
return (
<div className="main-container">
<h2 className="location">{locationName}</h2>
<div className="top">
<img
src={`https://openweathermap.org/img/wn/${weatherData.current.weather[0].icon}@2x.png`}
alt="Weather icon"
className="weather-icon"
/>
<h1 className="temp">{Math.floor(weatherData.current.temp)}°</h1>
<div className="units-container">
{unit === "metric" ? (
<div>
<div className="unit" id="C">
<h2>C</h2>
</div>
<div
className="unit"
id="F"
onClick={setUnit("imperial")}
>
<h2>F</h2>
</div>
<div className="background"></div>
</div>
) : (
<div>
<div className="unit" id="F">
<h2>F</h2>
</div>
<div
className="unit"
id="C"
onClick={setUnit("metric")}
>
<h2>C</h2>
</div>
<div className="background"></div>
</div>
)}
</div>
</div>
<div className="bottom">
<h2 className="description">
{weatherData.current.weather[0].description[0].toUpperCase()}
{weatherData.current.weather[0].description.substring(1)}
</h2>
<h4 className="timestamp">
Updated as of {convertTime(weatherData.current.dt, "HH-MM")}
</h4>
<div className="bottom-icons">
<div className="icons" id="top-icons">
<div className="icon-element">
Feels like {weatherData.current.feels_like}°
</div>
<div className="icon-element" id="wind">
Wind {weatherData.current.wind_speed}km
</div>
<div className="icon-element" id="visibility">
Visibility {Math.round(weatherData.current.visibility / 1000)} km
</div>
</div>
<div className="icons">
<div className="icon-element">
Barometer {weatherData.current.pressure} mb
</div>
<div className="icon-element" id="humidity">
Humidity {weatherData.current.humidity}%;
</div>
<div className="icon-element" id="dew">
Dew Point {Math.round(weatherData.current.dew_point)}°
</div>
</div>
</div>
</div>
</div>
);
};
目前 setUnit
正在被立即调用,改变状态并使其持续 re-render。相反,将 setUnit
函数传递给 onClick
以仅在触发 onClick
事件时调用它:onClick={() => setUnit("imperial")}
.
另一种选择是将 setUnit
更改为 return 事件处理程序。这种方法的一个优点是 event
与效果 -
const setUnit = (unit) => (event) => {
// access to `event` here
if (unit === "metric") {
console.log("metric!");
dispatch(unitActions.setToMetric());
} else {
console.log("imperial!");
dispatch(unitActions.setToImperial());
}
}
我喜欢这个选项,因为它使呼叫站点非常干净 -
<div
className="unit"
id="F"
onClick={setUnit("imperial")} {/* */}
children={<h2>F</h2>}
/>
相关:What do multiple arrow functions mean in JavaScript?