React 表单中输入字段的 onChange 道具上的 useDispatch()

useDispatch() on onChange prop of input field in React form

假设有 10 个输入字段数据。它们需要在表单页面、预览页面和确认页面等 3 个页面中持久化。

所以我猜数据肯定会作为 3 个页面的全局数据放在 Redux 中。 通常,我会在表单页面中创建 10 个 useState 挂钩来存储 10 data/states 并将 setState 分配给每个 onChange 道具。单击提交按钮后,它们将作为负载发送并更新到 redux 存储中。

然而,有一天我想出了一个主意,为什么我不将调度分配给每个 onChange 道具,因为 10 个数据最终将位于 redux 存储中。有了这个,我不需要创建 10 个 useState 挂钩,也不需要将相同的数据存储两次(在 useState 挂钩和 redux 存储中)。

但这会产生另一个问题,即频繁调用 redux 以使用 useSelector() 检索最新数据并使用 useDispatch() 分派新操作。但是频繁调用 redux store 应该没什么大不了的,因为它仍然是同步的,对吗?在这一点上我感到困惑和不确定。

因此,我想就此向 React 专家寻求建议...这是否意味着在我的情况下,仅使用 useDispatch(而不是同时使用 useState 和 useDispatch)更好?

//(A) : useState + useDispatch
 //create 10 useState hooks to store data/states. 
 //They are compiled and dispatched as payload to redux on button click

<input type="text" value={value1} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value2} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value3} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value4} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value5} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value6} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value7} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value8} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value9} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value10} onChange={()=>setValue(e.target.value)} />
<button onClick={handleSubmit}>Submit</button>

//(B) useDispatch only
 //valueSelector1 means the value is taken from the useSelector()

<input type="text" value={valueSelector1} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector2} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector3} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector4} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector5} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector6} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector7} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector8} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector9} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector10} onChange={()=>dispatch(setValue(e.target.value))} />
<button onClick={handleSubmit}>Submit</button>

我建议在 Redux 中将它们全部放在一起(一次调度),因为您的商店更新可能会导致不可预测的行为。 只需定义一个状态而不是多个状态并完成工作:

注意:每个输入的name属性与状态键相同

const [state,setState] = useState({value1:"fake",..., value9:"test"})

const handleValues=(e)=>{
  const {name,value} = e.target
  setSate({[name]:value})
}


<input type="text" value={value1} name="value1" onChange={handleValues} />
.
.
.
<input type="text" value={value9} name="value9" onChange={handleValues} />

<button onClick={handleSubmit}>Submit</button>

这两种方法(调用 useState 或调度 onChange 事件)在阻塞和非阻塞方面是不同的 UI 线程。

useState implementation -> 每当状态更新时 react 都会重新渲染组件,但对于频繁的状态更新,react 会将状态更新排队并在 UI 上进行更新。所以这是一个非阻塞的实现。

dispatch implementation 虽然 redux 以同步方式调度动作,因此它会阻止代码的执行,因此可能会增加 ui 屏幕上的更新时间和也可能会导致一些意想不到的结果。

因此,您可以采用在组件中管理本地状态的方式,并在运行中分派集体响应。这种方法还将帮助您在发送之前验证用户输入。

使用状态

const [payload,setPayload] = useState({value1:"dummy",..., value9:"dummy1"})

为输入元素添加唯一 ID

<input type="text" value={value1} id="value1" onChange={handleChange} />

实现handleChange函数

const handleChange =(e)=>{
   const {id,value} = e.target
   setPayload(initialState => { ...initialState, [id]:value })  //Give preference to provide the callback in place of object during setting the state
}

最后你可以将这个状态发送到 redux store

Your option A is more preferable:

1. Instead of using 10 different state/useState hooks, you should use a single state object of 10 input field data.

2. If we use useDispatch every time and call the redux store, then in that scenario, the store state will get updated. But if the user hadn't submitted that form or say user hadn't clicked submit button, then also redux data will be changed, which will create a problem.