假设有10个输入字段数据。它们需要在表单页、预览页和确认页等3个页面上持久存在。
所以我想这些数据肯定会作为3页的全局数据出现在Redux中。通常,我会在表单页面中创建10个useState挂钩来存储10个数据/状态,并将setState分配给每个onChange道具。一旦点击提交按钮,它们将作为有效负载进行调度,并更新到redux存储中。
然而,有一天我想出了一个主意,为什么我不把调度分配给每个onChange道具,因为10个数据最终会放在redux存储中。有了这个,我不需要创建10个useState钩子,并且感觉它是";冗余的";将相同的数据存储两次(在useState钩子和redux存储中(。
但这会产生另一个问题,即频繁调用redux以使用useSelector((检索最新数据,并使用useDispatch((调度新操作。但是频繁调用redux存储应该没什么大不了的,因为它仍然是同步的,对吧?在这一点上,我感到困惑和不确定。
因此,我想就此征求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>
这两种方法(调用useState或dispatch-onChange事件(在阻塞和非阻塞UI线程方面是不同的。
useState实现->只要状态更新了,react就会重新渲染组件,但对于频繁的状态更新,react会将状态更新排队并在UI上更新。所以这是一个非阻塞的实现。
dispatch实现虽然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存储
我建议在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>
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.