将状态重置为初始值,而不是最新的状态

时间:2020-09-07 08:08:59

标签: javascript reactjs react-hooks

docs中所述,在随后的重新渲染过程中,useState返回的第一个值将始终是应用更新后的最新状态。但是,我有一个用例,在后续重新渲染期间,状态需要重新初始化为props中提供的初始值。

将此示例视为我的用例的简化版本:

import React from "react";
import "./styles.css";

function Counter({ initialCount, handleChange }) {
  const [count, setCount] = React.useState(initialCount);

  const handleClick = (counter) => {
    setCount(count + counter);
    handleChange(count);
  };

  return (
    <>
      <h1>Counter {count}</h1>
      <button
        type="button"
        onClick={() => handleClick(1)}
        style={{ marginRight: "8px" }}
      >
        Add
      </button>
      <button type="button" onClick={() => handleClick(-1)}>
        Subtract
      </button>
    </>
  );
}

export default function App() {
  const [countOne, setCountOne] = React.useState(1);
  const [countTwo, setCountTwo] = React.useState(countOne % 2);

  return (
    <div className="App">
      <Counter
        initialCount={countOne}
        handleChange={(val) => setCountOne(val)}
      />
      <Counter
        initialCount={countTwo}
        handleChange={(val) => setCountTwo(val)}
      />
    </div>
  );
}

您也可以选中codesandbox

当我增加第一个计数器时,我希望第二个计数器根据第一个计数器的计数是偶数还是奇数将其重置为0或1(从原来的状态开始)。请注意,只有单向依赖,而没有任何循环一的含义;更改第二个计数器中的计数不应重置第一个计数器中的计数。

1 个答案:

答案 0 :(得分:1)

来自react组件文档

如果您想在道具更改时“重置”某些状态,请考虑... fully uncontrolled with a key

在要重置为其初始状态的组件上使用反应键。

当第一个countOne更新时,您可以使用Counter作为要重置的第二个Counter的密钥。提供countOne % 2作为第二个Counter的初始值。删除countTwo的重复状态,因为这是不必要的。并将handleChange回调设为可选,但将 new 状态值传递给回调(即count + counter),或使用效果来处理该回调,否则状态值不会保持同步。

function Counter({ initialCount, handleChange }) {
  const [count, setCount] = React.useState(initialCount);

  const handleClick = (counter) => {
    setCount(count + counter);
    handleChange && handleChange(count + counter);
  };

  // or

  useEffect(() => {
    handleChange && handleChange(count);
  }, [count, handleChange]);

  const handleClick = (counter) => {
    setCount(count + counter);
  };

  return (
    <>
      <h1>Counter {count}</h1>
      <button
        type="button"
        onClick={() => handleClick(1)}
        style={{ marginRight: "8px" }}
      >
        Add
      </button>
      <button type="button" onClick={() => handleClick(-1)}>
        Subtract
      </button>
    </>
  );
}

export default function App() {
  const [countOne, setCountOne] = React.useState(1);

  return (
    <div className="App">
      <Counter
        initialCount={countOne}
        handleChange={setCountOne}
      />
      <Counter
        key={countOne}
        initialCount={countOne % 2}
      />
    </div>
  );
}

Edit reset-state-to-initial-value-instead-of-most-updated-recent-one

如果您不想使用react键将其重置为初始状态,则可以在第二个useEffect钩子中提供另一个道具作为依赖项,以重置为提供的{{1} }。

initialValue

function Counter2({ initialCount, handleChange, reset }) { const [count, setCount] = React.useState(initialCount); useEffect(() => { handleChange && handleChange(count); }, [count, handleChange]); useEffect(() => { setCount(initialCount); }, [reset, initialCount]); const handleClick = (counter) => { setCount(count + counter); }; return ( <> <h1>Counter 2: {count}</h1> <button type="button" onClick={() => handleClick(1)} style={{ marginRight: "8px" }} > Add </button> <button type="button" onClick={() => handleClick(-1)}> Subtract </button> </> ); } 传递给countOne道具,以便在reset更新时重置计数。

countOne