使用React挂钩设置组件状态后如何从组件调用事件?

问题描述 投票:1回答:1

我有两个input,其值反映了计数器的状态。其中一个是名为LazyInput的组件的一部分,该组件不会仅在输入模糊时立即更新状态。但是,我希望LazyInput不会表现得很“懒惰”,并且只要通过 键更改值,就立即立即更新计数器。

App代码(包括普通的input)如下:

const {Fragment, useState, useEffect} = React;

function LazyInput({ name, value, onComplete }) {
  const initialValue = value;
  const [lazyValue, setLazyValue] = useState(value);

  // Sync to state changed by the regular input
  useEffect(() => {
    setLazyValue(value);
  }, [value]);

  const handleKeyDown = e => {
    const { key, target } = e;
    switch (key) {
      case "ArrowUp": {
        setLazyValue(parseFloat(lazyValue) + 1);
        onComplete(e);
        break;
      }
      case "ArrowDown": {
        setLazyValue(parseFloat(lazyValue) - 1);
        onComplete(e);
        break;
      }
      case "Escape": {
        setLazyValue(initialValue);
        target.blur();
        break;
      }
      case "Enter": {
        target.blur();
        break;
      }
      default:
        return;
    }
  };
  return (
    <input
      name={name}
      value={lazyValue}
      onChange={e => setLazyValue(e.target.value)}
      onKeyDown={e => handleKeyDown(e)}
      onBlur={e => onComplete(e)}
    />
  );
}

function App() {
  const [counter, setCounter] = useState(0);

  function handleCounterChange(e) {
    setCounter(parseFloat(e.target.value));
  }

  return (
    <Fragment>
      <div>Counter: {counter}</div>
      <LazyInput
        name="counter"
        value={counter}
        onComplete={e => handleCounterChange(e)}
      />
      <input
        value={counter}
        type="number"
        onChange={e => handleCounterChange(e)}
      />
    </Fragment>
  );
}

ReactDOM.render(<App />, document.getElementById("app"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="app"></div>

键会在onComplete(e)之前触发setLazyValue()功能–我想是因为它是异步的–与状态失去同步。

出于相同的原因,按Esc会使input模糊,然后将其值重置为initialValue

我知道setState()类回调has been substituted by the useEffect() hook,但:

  1. 如何从useEffect()调用onComplete(e)功能?
  2. [仅当按下 键而不是其他所有键时才怎么做?

感谢您的帮助,这里是useEffect()

javascript reactjs react-hooks keyboard-events use-effect
1个回答
0
投票

我建议将interactive sandboxcounter传递给setCounter。然后LazyInput可以使用useEffect作为依赖项。每当更改counter时,counter挂钩就会触发。

useEffect
function LazyInput({ name, counter, setCounter}) {
    const [initialValue] = useState(counter);

  // Sync to state changed by the regular input
  useEffect(() => {
    target.blur();
  }, [counter]);

  const handleKeyDown = e => {
    const { key, target } = e;
    switch (key) {
      case "ArrowUp": {
        setCounter(parseFloat(counter) + 1);
        break;
      }
      case "ArrowDown": {
        setCounter(parseFloat(counter) - 1);
        break;
      }
      case "Escape": {
        setCounter(initialValue);
        break;
      }
      case "Enter": {
        target.blur();
        break;
      }
      default:
        return;
    }
...
© www.soinside.com 2019 - 2024. All rights reserved.