React 如何使用 refs 来聚焦/模糊?

Posted

技术标签:

【中文标题】React 如何使用 refs 来聚焦/模糊?【英文标题】:React how to use refs to focus/blur? 【发布时间】:2021-06-14 11:52:50 【问题描述】:

我正在阅读来自 Reactjs.org 的 React 文档,但它似乎不适用于我想做的事情。

我想渲染一个带有嵌套 div 的组件。单击每个嵌套的 div 后,它会变成一个输入。在特定 div 之外单击时,它会将输入转换回 div。

我想使用带有模糊/焦点的参考来实现这一点,但我似乎无法弄清楚如何让它工作。

这是我的组件到目前为止的样子,它是一个子组件:

constructor(props) 
    super(props);
    this.textInput = React.createRef();

focusRef = () => 
    this.textInput.current.focus();

focusEvent = () => 
    console.log("focus event.");

render() 
    let item = <div
        className="item-class"
        ref=this.textInput
        onFocus=this.showIt
        onClick=this.focusRef>Item Name</div>
    return(<div>item</div>)

查看react.js.org提供的示例代码,我很奇怪为什么没有onFocus事件。这不是必需的吗?当元素获得焦点时,还会如何触发事件?在我的代码中,focusRef 被触发但focusEvent 没有被触发,这也是我想不通的。其次,如何检测模糊/失去焦点,以便将输入交换回 div?最后,我对在 div 和 input 之间交换元素的焦点/模糊事件如何与渲染一起工作感到困惑,每次发生这种交换时我不需要重新渲染,也就是每次元素接收/失去焦点时都需要重新渲染吗?这不需要在渲染之间保持元素的焦点(或缺乏焦点)吗?

如果可能,我更喜欢不涉及挂钩的解决方案。

【问题讨论】:

关注input 而不是div。尝试将 div 更改为 input 【参考方案1】:

为了使div 元素具有焦点,它需要可交互。为 div 添加标签索引,以便获得焦点。

function App() 
  return (
    <div className="App">
      <div 
        tabIndex=0 
        onFocus=() => console.log('focus') 
        onBlur=() => console.log('blur')
      >
        Click or tab to me!
      </div>
    </div>
  );


const rootElement = document.getElementById("root");
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  rootElement
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

这是一个可切换/可聚焦的 div/输入。它使用状态来保存是否应呈现 div 或输入,并使用 ref 和 componentDidUpdate 方法在切换视图后重新聚焦输入。

class App extends React.Component 
  textInputRef = React.createRef();

  state = 
    isInput: false,
    value: "test"
  ;

  componentDidUpdate() 
    const  isInput  = this.state;
    isInput && this.textInputRef.current.focus();
  

  handleFocus = () => 
    console.log("focus");
    this.setState( isInput: true );
  ;

  handleBlur = () => 
    console.log("blur");
    this.setState( isInput: false );
  ;

  handleChange = (e) => this.setState( value: e.target.value );

  render() 
    const  isInput, value  = this.state;
    return (
      <div className="App">
        isInput ? (
          <input
            type="text"
            ref=this.textInputRef
            value=value
            onBlur=this.handleBlur
            onChange=this.handleChange
          />
        ) : (
          <div tabIndex=0 onFocus=this.handleFocus>
            value
          </div>
        )
      </div>
    );
  


const rootElement = document.getElementById("root");
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  rootElement
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

【讨论】:

我明白了,我以前从未听说过标签索引。不管你的例子帮助我理解了一些事情。我会尝试实现类似的东西。 @JonathanYap 尽管您应该尝试将您的 SO 帖子限制在一个特定的问题/问题上,但我正在开发一个实现可切换 div/input 的代码框,因为我发现这是一个有趣的想法。跨度> @JonathanYap 用 a 为您所寻求的工作解决方案更新了答案。请检查一下,看看你的想法。

以上是关于React 如何使用 refs 来聚焦/模糊?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 React ref 聚焦和选择复选框?

react中input自动聚焦问题

将输入字段聚焦在React组件中 - 尝试创建ref时出现类型错误

如何模糊语义-ui-react 中提供的输入?

如何使用 React 和 Redux 从另一个组件访问 ref?

如何使用 React Ref 调用 video.play()?