React Hooks - 如何使用使一个状态依赖于另一个状态?

bal*_*zar 8 javascript reactjs react-hooks

我最近开始在 React 中使用钩子,经常遇到这个问题:我创建了一个由所有组件使用的第一个大状态,但为了简单起见,组件的一些较小部分划分了这个状态并创建了自己的状态。

例如

import React, { useState } from "react";

const initialFilters = {
  name: "",
  code: ""
};

function Filter({ value, setFilters }) {
  const [tempValue, setTempValue] = useState(value);

  return (
    <input
      value={tempValue}
      onChange={e => setTempValue(e.target.value)}
      onBlur={() => setFilters(tempValue)}
    />
  );
}

function App() {
  const [filters, setFilters] = useState(initialFilters);
  const agents = [
    { name: "bob", code: "123" },
    { name: "burger", code: "3123" },
    { name: "sponge", code: "34" }
  ];

  return (
    <div>
      <label>Name filter</label>
      <Filter
        value={filters.name}
        setFilters={value =>
          setFilters(filters => ({ ...filters, name: value }))
        }
      />
      <label>Code filter</label>
      <Filter
        value={filters.code}
        setFilters={value =>
          setFilters(filters => ({ ...filters, code: value }))
        }
      />
      <button onClick={() => setFilters(initialFilters)}>Reset filters</button>
      <ul>
        {agents
          .filter(
            agent =>
              agent.name.includes(filters.name) &&
              agent.code.includes(filters.code)
          )
          .map((agent, i) => (
            <li key={i}>
              name: {agent.name} - code: {agent.code}
            </li>
          ))}
      </ul>
    </div>
  );
}

export default App;
Run Code Online (Sandbox Code Playgroud)

CodeSandox 可以在这里找到

在此示例中,过滤器工作正常,但当我们使用“重置”按钮时,它们的值不会被清空。

过滤器创建自己的状态,仅在模糊时调度新状态,并且仍然受到控制。我想我可以在这里使用 ref ,但我使用这个例子来展示一个简单的状态依赖于另一个状态(因此依赖于 props )的情况。

我应该如何以惯用的 React 方式实现这一点?

小智 9

您可以使用useEffect钩子。第一个参数是一个函数,第二个参数是一个依赖项数组。当依赖项的值发生更改时,该函数将再次执行。

import { useEffect } from 'react';

// ....code removed....

  useEffect(() => {
    setTempValue(value);
  }, [value]);

// ....code removed....
Run Code Online (Sandbox Code Playgroud)

进行更改的沙箱:https://codesandbox.io/s/kind-bogdan-ljugv