简体   繁体   English

在 React 表单中输入字段的 onChange 属性上使用 Dispatch()

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

Let's say there are 10 input field data.假设有 10 个输入字段数据。 They are required to persist across 3 pages such as form page, preview page and confirmation page.它们需要跨越 3 个页面,例如表单页面、预览页面和确认页面。

So I guess the data would definitely to sit in Redux as global data for the 3 pages.所以我想这些数据肯定会放在 Redux 作为 3 页的全局数据。 Normally, I would create 10 useState hooks in the form page to store the 10 data/states and assign setState to every onChange prop.通常,我会在表单页面中创建 10 个 useState 挂钩来存储 10 个数据/状态并将 setState 分配给每个 onChange 道具。 Once the submit button is clicked, they will be dispatched as payload and got updated into redux store.单击提交按钮后,它们将作为有效负载发送并更新到 redux 存储中。

However, one day I came up with an idea why don't I just assign dispatch to every onChange prop since the 10 data will eventually sit in redux store.但是,有一天我想出了一个主意,为什么不将调度分配给每个 onChange 道具,因为这 10 个数据最终将位于 redux 存储中。 With this, I do not need to create 10 useState hooks and feel it is "redundant" to store same data two times ( in both useState hook and redux store).有了这个,我不需要创建 10 个 useState 钩子,并且觉得两次存储相同的数据是“冗余的”(在 useState 钩子和 redux 存储中)。

But this yields another issue, which is frequent call to redux to retrieve newest data using useSelector() and dispatch new action using useDispatch().但这会产生另一个问题,即频繁调用 redux 以使用 useSelector() 检索最新数据并使用 useDispatch() 调度新操作。 But frequent call to redux store should not be a big deal since it is still synchronous right?但是频繁调用 redux 商店应该没什么大不了的,因为它仍然是同步的,对吧? I got confused and feeling unsure at this point.在这一点上,我感到困惑和不确定。

Hence, I would like to seek advices from React experts on this...Does that mean in my case, using useDispatch only (not both useState and useDispatch) is better?因此,我想就此向 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>

I recommend putting them all together (with one dispatch) in Redux because maybe there will be unpredictable behavior due to updates in your store.我建议将它们全部放在一起(一次分派)在 Redux 中,因为由于商店中的更新可能会出现不可预测的行为。 Just define one state instead of many states and do the job:只需定义一个 state 而不是许多状态并完成工作:

Note : the name property of each input is same as the state's key.注意:每个输入的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>

Both the approaches (calling useState or dispatch onChange event) are different in terms of blocking and non-blocking UI thread.这两种方法(调用 useState 或调度 onChange 事件)在阻塞和非阻塞 UI 线程方面是不同的。

useState implementation -> Whenever the state updated react re-renders the component but for the frequent state update react queues the state update and update it on UI. useState implementation -> 每当 state 更新时,react 都会重新渲染组件,但对于频繁的 state 更新,react 会排队 state 更新并在 UI 上更新它。 So this is a non-blocking implementation.所以这是一个非阻塞的实现。

dispatch implementation While redux dispatch the actions in a synchronous manner, so it blocks the execution of code due to which it may increase ui update time on screen and also may cause some unexpected results. dispatch implementation redux 以同步的方式调度动作,因此它阻塞了代码的执行,因此可能会增加屏幕上的 ui 更新时间,也可能导致一些意想不到的结果。

So you can go with the way managing the local state in the component and dispatch the collective response in on go.因此,您可以通过在组件中管理本地 state 的方式来 go 并在 go 上发送集体响应。 This approach will also help you to validate the user input as well before dispatching it.这种方法还将帮助您在分派之前验证用户输入。

Use state使用 state

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

Add a unique id with the input element使用输入元素添加唯一 id

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

Implement the handleChange function实现handleChange function

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
}

And at the end you can dispatch this state to redux store最后,您可以将此 state 发送到 redux 商店

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.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React TypeScript 通过输入字段 onChange 提交表单 - React TypeScript Submit Form Through Input Field onChange 使用事件传播时反应警告“您在没有 `onChange` 处理程序的情况下向表单字段提供了 `value` 道具...” - React warning "You provided a `value` prop to a form field without an `onChange` handler..." when using event propagation 警告:您在没有 `onChange` 处理程序的情况下为表单字段提供了 `checked` 属性 - Warning: You provided a `checked` prop to a form field without an `onChange` handler React 测试库不在快照中显示输入 onChange 道具 - React testing library not displaying input onChange prop in snapshot 反应:onChange不会将值更新为输入字段 - React: onChange not updating value to input field 失败的道具类型:您在没有“onChange”处理程序的情况下向表单字段提供了“已检查”道具 - Failed prop type: You provided a `checked` prop to a form field without an `onChange` handler onChange事件没有使用React触发输入字段 - onChange event not firing for input field with React 以 react-hook-form 的 onChange 输入 - onChange input in react-hook-form 在我调用 onChange 之前,React Hook Form 不会验证嵌套的输入字段 - React Hook Form not validating nested input field until I call onChange 表单 propType 失败:您在没有 `onChange` 处理程序的情况下向表单字段提供了 `value` 道具 - Failed form propType: You provided a `value` prop to a form field without an `onChange` handler
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM