首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React在Redux中存储Ref元素

React在Redux中存储Ref元素
EN

Stack Overflow用户
提问于 2020-08-09 18:43:52
回答 1查看 3.2K关注 0票数 1

你将如何在Redux中存储Ref元素,你会这样做吗?

我有一个包含一些表单元素的组件,如果用户离开页面又回来,我需要在其中存储用户选择的表单字段的状态。

我尝试这样注册Redux中的每个输入域(我使用的是Blueprint.js中的<InputGroup>组件):

代码语言:javascript
复制
<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上迭代,以便在页面加载时聚焦于正确的元素。但这感觉像是黑客攻击。你会怎么做呢?

EN

回答 1

Stack Overflow用户

发布于 2020-08-10 19:39:14

我不确定我是否会使用它们来达到这个目的,但它不会是第一个这样做的方法。

有一个React状态来存储聚焦表单元素的唯一标识符是非常好的。每个表单元素,或者一般的任何元素,都可以有一个唯一的标识符,它可以只是一个字符串。你可以将它们保存在你的应用程序的redux store中的任何持久性中,比如web存储。

当您离开时,您可以通过使用React效果将该状态提交到redux存储或持久化。

代码语言:javascript
复制
    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]);

另一个选择

代码语言:javascript
复制
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。

代码语言:javascript
复制
<input onFocus={e => setLastFocusedElementId(e.target.id)} />
<input onFocus={e => setLastFocusedElementId(e.dataset.id)} />

我还需要一种方法,当您重新打开带有表单元素的页面时,使用您选择的源中的数据来聚焦最后一个聚焦的元素。你可以像这样给每个元素添加autoFocus属性

代码语言:javascript
复制
<input autoFocus={"elementID"===lastFocusedElementId} />

最后,如果您的用户离开表单页面时没有聚焦任何元素,那么您可能希望将id设置为一个基值,如空字符串之类。在这种情况下,您需要将模糊事件与onBlur处理程序一起使用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63325303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档