你将如何在Redux中存储Ref元素,你会这样做吗?
我有一个包含一些表单元素的组件,如果用户离开页面又回来,我需要在其中存储用户选择的表单字段的状态。
我尝试这样注册Redux中的每个输入域(我使用的是Blueprint.js中的<InputGroup>组件):
<InputGroup
inputRef={(ref) => { dispatch(addRefToState(ref)) }}
...more props...
/>这导致了循环JSON引用错误,因为Redux将ref元素序列化为JSON,以便将其保存到localStorage。然后,我尝试用我在Stackoverflow上找到的代码片段“安全”地将对象串起来,在将对象转换为JSON之前删除所有循环引用。这是可行的,但是Ref元素仍然很大,以至于存储在状态中的3-5个Ref变成了3MB的localStorage,我的浏览器开始变得非常慢。此外,我担心我是否可以实际使用该Ref对象来引用我的组件,因为我知道我实际上修改了Ref对象。我还没有尝试过,因为字符串对象的性能太差了。
我正在考虑放弃“React方式”,只是在每个组件上添加唯一的in,将这些in存储在Redux中,并使用document.querySelector在DOM上迭代,以便在页面加载时聚焦于正确的元素。但这感觉像是黑客攻击。你会怎么做呢?
发布于 2020-08-10 19:39:14
我不确定我是否会使用它们来达到这个目的,但它不会是第一个这样做的方法。
有一个React状态来存储聚焦表单元素的唯一标识符是非常好的。每个表单元素,或者一般的任何元素,都可以有一个唯一的标识符,它可以只是一个字符串。你可以将它们保存在你的应用程序的redux store中的任何持久性中,比如web存储。
当您离开时,您可以通过使用React效果将该状态提交到redux存储或持久化。
const [lastFocusedElementId, setLastFocusedElementId] = useState();
useEffect(() => {
// here you can get last focused element id from props, or from directly storage etc, previously if any
if(props.lastFocusedElID) {
setLastFocusedElementId(props.lastFocusedElID);
}
// here in return you commit last focused id
return saveLastFocusedElementID(lastFocusedElementId) // an action creator that saves to the redux store before every rerender of component and before unmount
}, [props.lastFocusedElID]);另一个选择
const [lastFocusedElementId, setLastFocusedElementId] = useState();
useEffect(() => {
const lastFocusedElID = window.localStorage.getItem(lastFocusedElementId);
if (lastFocusedElID) {
setLastFocusedElementId(lastFocusedElID);
}
return window.localStorage.setItem('lastFocusedElementId', lastFocusedElementId);
}, []);更不用说您需要在想要设置最后一个焦点元素ID的表单元素上使用onFocus。Id可以在您选择的属性上,它可以是id属性,也可以使用data-*属性。我在这里展示了id和data-id。
<input onFocus={e => setLastFocusedElementId(e.target.id)} />
<input onFocus={e => setLastFocusedElementId(e.dataset.id)} />我还需要一种方法,当您重新打开带有表单元素的页面时,使用您选择的源中的数据来聚焦最后一个聚焦的元素。你可以像这样给每个元素添加autoFocus属性
<input autoFocus={"elementID"===lastFocusedElementId} />最后,如果您的用户离开表单页面时没有聚焦任何元素,那么您可能希望将id设置为一个基值,如空字符串之类。在这种情况下,您需要将模糊事件与onBlur处理程序一起使用。
https://stackoverflow.com/questions/63325303
复制相似问题