三元内部的函数导致无限循环

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?