我正在调试一款Reaction应用程序,注意到我的一些函数被多次调用,我无法解释.

我最初认为这是某种"开发人员功能",并try 运行构建,如果不应该调用的API被调用一次而不是两次,我所能看到的就是:

import { useCallback, useState } from "react";

function App() {
  const cities = ["montreal", "london", "shanghai"];

  const [city, setCity] = useState(cities[0]);

  const getCityParameter = useCallback(
    (newCity) => {
      console.log("[1] getCityParameter");
      console.log(`newCity: ${newCity}`);
      console.log(`city: ${city}`);
      return (newCity ?? city).toUpperCase();
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [city]
  );
  const [cityParameter, setCityParameter] = useState(getCityParameter());

  const handleChange = useCallback(
    (event) => {
      const newCity = event?.target.value;
      console.log("handleCityChange");
      console.log(`newCity: ${newCity}`);
      if (newCity !== undefined) {
        setCity(newCity);
      }
      const newCityParameter = getCityParameter(newCity);
      setCityParameter(newCityParameter);
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [city]
  );

  return (
    <>
      <select onChange={handleChange} value={city}>
        {cities.map((city) => {
          return (
            <option value={city} key={city}>
              {city}
            </option>
          );
        })}
      </select>
      <div>{cityParameter}</div>
    </>
  );
}

export default App;

我在这里创建了这个代码沙箱:https://codesandbox.io/s/restless-butterfly-brh7fk?file=/src/App.js

如果清除控制台日志(log)并更改下拉列表,您会注意到getCityParameter被调用了3次,而我预计它只会被调用一次.

这似乎是一个相当低级的react 功能,我为这个"不那么小"的例子道歉--这是我能想到的最好的重现行为的方法.

有谁能解释一下吗?

推荐答案

在更改处理程序中,首先:

const newCityParameter = getCityParameter(newCity);

所以这是getCityParameter的一个电话.然后,组件重新呈现,因为调用了状态设置器.这一点:

const [cityParameter, setCityParameter] = useState(getCityParameter());

就像在做

const result = getCityParameter();
const [cityParameter, setCityParameter] = useState(result);

每次呈现组件时都会再次调用该函数,因此您可以再次看到它.最后,because you're in strict mode:

root.render(
  <StrictMode>
    <App />
  </StrictMode>
);

该应用程序再次重新渲染,因此getCityParameter再次运行,当下拉菜单更改时,它总共被调用了3次.

当然,初始状态值仅在组件挂载时使用,这意味着每次组件在不需要时呈现时调用函数可能被视为不必要或令人困惑.如果希望getCityParameter在重新渲染时不被调用,并且仅在装载时被调用以确定初始状态值use the functional version of useState.变化

const [cityParameter, setCityParameter] = useState(getCityParameter());

const [cityParameter, setCityParameter] = useState(getCityParameter);

Reactjs相关问答推荐

在react中向数组状态添加值时出错

避风港访问端口以包含Reaction应用程序

如何将图像(在代码中称为自己)定位在蓝色圈内的点上?我正在使用material UI和Reaction

REACTION 18功能组件正在开发中的S

捕获表单数据时的Reactjs问题

Google Firestore无法读取图像-react

如何在与AntD的react 中限制文件上传和显示消息?

react 挂钩-使用有效澄清

使用experial_useFormState将参数传递给服务器操作

在遵循 react-navigation 的官方文档时收到警告消息

每次状态更改时都会提交react 表单

FlatList 不在 React Native 中呈现项目

在 React 中使用复选框管理状态

useState 在生命周期中的位置

在 redux 中分派到另一个减少时状态值不会改变

list 组件未按预期运行

如何从其他组件访问 useQuery refetch 方法?

如何不旋转 mui 自动完成弹出图标?

在react 钩子中将数组添加到数组状态给出一个数字

在 Redux 中更新布尔状态时出错