反应-结合即时输入和去抖动输出

时间:2020-03-30 05:45:47

标签: javascript reactjs

我在组件中有一个组件。由于复杂的计算,父组件(窗体)的渲染成本很高。因此,如果我在子组件(UserForm)的用户名输入中按住一个键,该页面将开始丢弃帧(新字符不会显示一点),因为它会尽快渲染父项(这很昂贵) 。为了解决这个问题,我开始将用户名prop的本地实例存储在子组件中的状态中,然后在将该状态传递给父级之前将其去抖。

问题是,当子组件中的反跳仍在进行时,当父组件修改用户名(例如通过还原更改)时,父子组件的反跳输出会覆盖父组件的修改。

const UserForm = ({ value, onChange }) => {
  const debouncedOnChange = useCallback(
    lodash.debounce(updatedValue => {
      onChange(updatedValue);
    }, 500),
    [onChange]
  );

  const [username, setUsername] = useState(value.username);
  useEffect(() => {
    setUsername(value.username);
  }, [value.username]);

  const handleUsernameOnChange = useCallback(
    event => {
      setUsername(event.target.value);
      debouncedOnChange({
        ...value,
        username: event.target.value,
      });
    },
    [debouncedOnChange]
  );

  return (
    <div>
      <input value={username} onChange={handleUsernameOnChange} />
    </div>
  );
};

const INITIAL_STATE = {
  user: {
    username: 'John',
  },
  dog: {
    name: 'Cliffard'
  }
};

// <Form/> Is expensive to render because of complex calculations
const Form = () => {
  const [value, setValue] = useState(INITIAL_STATE);

  const [backup, setBackup] = useState(INITIAL_STATE);

  return (
    <form>
      <UserForm
        value={value.user}
        onChange={updatedUserFormValue => {
          setValue({
            ...value,
            updatedUserFormValue,
          });
        }}
      />
      <button
        onClick={() => {
          setValue({
            ...value,
            user: { ...backup.user },
          });
        }}
      >
        Reset User Form
      </button>
    </form>
  );
};

0 个答案:

没有答案