重新渲染后哪个组件需要键来保持焦点?

Posted

技术标签:

【中文标题】重新渲染后哪个组件需要键来保持焦点?【英文标题】:Which component needs keys to keep focus after rerender? 【发布时间】:2022-01-07 22:55:47 【问题描述】:

我被这个问题困扰了好几天,我已经浏览了React.js - input losing focus when rerendering,其中列出了一些关于失去对第一次击键的关注的建议和解决方案 - 但我仍然没有设法解决它。我此时惊慌失措,所以可能错过了明显的解决方案。

“其他”TextEditor 在第一次击键后总是失去焦点 如果资源超过 1 个,“资源”文本编辑器会失去焦点。因此,必须有一些正确的东西才能让它只使用一个 TextEditor 来保持焦点...

这是一个显示焦点丢失的代码框:https://codesandbox.io/s/fervent-tereshkova-bz1wz?file=/agenda.js

【问题讨论】:

你能在代码沙盒或类似工具中创建一个最小可重现的例子吗?仅从您的示例代码中很难说出任何事情。如果删除所有不必要的代码,通常会发现错误。 <TextEditor /> -组件中有什么特别之处吗?如何更新表单中的文本? 我只是试图生成一个代码框,令人沮丧的是它在这种情况下工作:codesandbox.io/s/fervent-tereshkova-bz1wz?file=/agenda.js 在我的本地,如果我将 切换到 我仍然有同样的问题:/所以它不存在 这通常意味着每次击键时都会重新创建整个表单。在您的代码框中,表单不会在按键上重新呈现,这意味着表单中的数据不受反应控制。你的设置在你当地是一样的吗? codeandbox-example 是否包含在另一个组件中,可能会在每次击键时重新创建? 开始:我非常感谢您能帮助我。我今天又坚持了 3 个小时。所以,现在我再次尝试使用 而不是 它确实在本地工作。我也无法让 TextEditor 在沙箱中工作,我已经添加了 slate 依赖项...codesandbox.io/s/fervent-tereshkova-bz1wz?file=/TextEditor.js 我很茫然。我在这个 bug 上花费的时间比所有功能加起来还要多。 我得到了 CODESANDBOX 的工作!!!好的,现在你会看到在任何文本编辑器中的第一次击键后失去焦点 【参考方案1】:
onChange = ( value ) => 
    if (this.props.onChange) 
      // Check to see if the document value really has changed
      if (value.document !== this.state.value.document) 
        this.props.onChange(value);  //  <----- This line is ruining it for you
      
    
    this.setState( value );
  ;

指示的行毁了你,我不明白你需要它做什么。 如果您想在状态真正改变时触发回调,您应该通过componentWillUpdate(object nextProps, object nextState) 执行此操作,并将nextState.value.documentthis.state.value.document 进行比较,如下所示:

componentWillUpdate = (object nextProps, object nextState) => 
  if (nextState.value.document !== this.state.value.document)
    this.props.onChange(nextState.value);

...或者您可以在状态更新后使用setState callback 触发代码:

onChange = ( value ) => 
  var newDocValue = value.document;
  var oldDocValue = this.state.value.document;
  this.setState( value , () => 
    if (oldDocValue !== newDocValue)
      this.props.onChange(newDocValue);
  );

我个人会将整个组件重写为一个函数组件,因为我认为使用 useEffect 钩子可以更轻松地处理生命周期和更改反应。

【讨论】:

嗯,第一个使用 componentWillUpdate 的建议没有做到,会尝试其他的!谢谢你。也同意重新重写功能,我计划这样做但不在这个 sprint 中。

以上是关于重新渲染后哪个组件需要键来保持焦点?的主要内容,如果未能解决你的问题,请参考以下文章

使用 navigate('/path') 后重新渲染组件

子组件API获取请求后重新渲染App组件?

vue3 生命周期

组件挂载时 Ref.current 未定义,当我需要它时它不会导致重新渲染

当组件包含帮助程序时如何重新渲染组件?

如何在 Angular 2 中强制组件重新渲染?