警报在反应中出现两次

Alert appearing twice in react

为什么这个警告框在一个简单的 useReducer 应用程序中出现两次,

Click here 对于 codesandbox link,

重新生成场景

  1. 使用向上箭头增加输入值(只按一次)
  2. 通过向下键减小输入值(只按一次)

这是代码

import "./styles.css";
import { useReducer } from "react";
const reducerFunction = (state, action) => {
  switch (action.type) {
    case "testing": {
      if (action.payload.value > 0) {
        return { ...state, testing: action.payload.value };
      } else {
        alert("some message");
        return state;
      }
    }
    default: {
      throw new Error("Invalid Action");
    }
  }
};
export default function App() {
  const defaultValue = {
    testing: 0
  };
  const [state, dispatch] = useReducer(reducerFunction, defaultValue);

  return (
    <input
      value={state.testing}
      onChange={(e) => {
        dispatch({ type: "testing", payload: { value: e.target.value } });
      }}
      type="number"
    />
  );
}

你的初始状态是这样的:

const defaultValue = {
  testing: 0
};

它绑定到输入值,但随后从您的减速器返回:

return { inputValue: action.payload.value };

导致 testing 成为 undefined

您可以在控制台中看到此错误:

Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components

您的代码应该是

return {...state, testing: action.payload.value };

这将显示一个警报并防止出现负值

您正在使用 StrictMode,它调用传递给 useReducer 的函数两次,来自文档:

Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:

Functions passed to useState, useMemo, or useReducer

// Remove Strict.Mode
ReactDOM.render(
  <App />,
  rootElement
);

丹尼斯对导致此处问题的严格模式行为是正确的。

如果你在项目中仍然需要使用严格模式,你可以使用下面的代码更新相同的-

Code Sandbox Link