【问题标题】:How to implement a react controlled input using useReducer?如何使用 useReducer 实现反应控制输入?
【发布时间】:2020-09-02 05:29:30
【问题描述】:

我的目标是使用 useReducer 钩子实现 React 控制输入。

在减速器内部,我需要event.target.valueevent.target.selectionStart 来获取当前值和插入符号位置。所以我考虑将event 作为payload 发送给ON_CHANGE 操作。

这就是我正在尝试的:

https://codesandbox.io/s/optimistic-edison-xypvn

function reducer(state = "", action) {
  console.log("From reducer... action.type: " + action.type);
  switch (action.type) {
    case "ON_CHANGE": {
      const event = action.payload;
      const caretPosition = event.target.selectionStart;
      const newValue = event.target.value;
      console.log("From reducer... event.target.value: " + event.target.value);
      console.log(
        "From reducer... event.target.selectionStart: " + caretPosition
      );
      return newValue;
    }
    default: {
      return state;
    }
  }
}

export default function App() {
  console.log("Rendering App...");

  const [state, dispatch] = useReducer(reducer, "");

  return (
    <div className="App">
      <input
        value={state}
        onChange={event => dispatch({ type: "ON_CHANGE", payload: event })}
      />
    </div>
  );
}

它适用于输入的第一个字母,但它在第二个时中断。

这是错误:

警告:出于性能原因,此合成事件会被重复使用。如果您看到这一点,则表示您正在访问已发布/无效合成事件上的属性 target。这设置为空。如果您必须保留原始合成事件,请使用 event.persist()。请参阅react-event-pooling 了解更多信息。

我该怎么办?我需要在哪里致电event.persist()。我应该在reducer 上执行此操作,还是需要在将其作为参数发送之前在onChange() 处理程序中执行此操作。

或者最好只发送这些属性,而不是发送完整的event 对象?

喜欢:

onChange={ event => 
  dispatch({ 
    type: "ON_CHANGE", 
    payload: {
      value: event.target.value,
      caretPosition: event.target.selectionStart
    }
  })
}

【问题讨论】:

    标签: javascript reactjs input react-hooks use-reducer


    【解决方案1】:

    只需传递event.target.value,因为就像错误所说的那样,synthetic events 不会持续存在。

    function reducer(state = "", action) {
      switch (action.type) {
        case "ON_CHANGE": {
          const newValue = action.payload;
          return newValue;
        }
        default: {
          return state;
        }
      }
    }
    
    export default function App() {
      const [state, dispatch] = useReducer(reducer, "");
    
      return (
        <div className="App">
          <input
            value={state}
            onChange={event =>
              dispatch({ type: "ON_CHANGE", payload: event.target.value })
            }
          />
        </div>
      );
    }
    

    【讨论】:

    • 我还需要event.target.selectionStart 属性。我应该在有效负载中发送这两个属性吗?或者我应该打电话给event.persist() 并发送整个event。你会选择哪种方法?谢谢!
    • 是的,传入有效载荷
    猜你喜欢
    • 2021-12-10
    • 2020-08-27
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多