繁体   English   中英

如果我不拥有该代码,如何将 Ref 分配给 React 组件中的按钮? 我想集中注意力

[英]How to assign a Ref to a button in a React component if I don't own that code? I want to focus it

我正在研究 React。 还有一个团队向我们展示了一个组件,其中有一个按钮。 它是我们存储库的依赖项。 我希望在完成特定操作时使该按钮成为焦点。 我想使用 refs 或任何其他可接受的方式来做到这一点。

myCode.js

focusExternalButton() {
  // some code that focuses the button in the external component
}

render() {

  return {
    <div>
      <ExternalButtonComponent/>
      <button onClick={this.focusExternalButton}>submit</button>
    </div>
  }
} 

ExternalButtonComponent.js

render() {
  return <div><button id="btn-external">This is a button</button></div>
}

单击按钮时如何将焦点放在外部按钮上? 我正在考虑参考,但我不确定如何实现它。

让我有点吃惊的是,外部组件使用id在页面中多次渲染它会导致页面上出现重复的id ,这不是有效的 HTML。

尽管如此,是的,您可以直接查询 DOM,尽管我可能会在挂载时执行此操作并将结果返回的元素存储在ref中。

 const { useEffect, useRef } = React; function App() { const buttonRef = useRef(); useEffect(() => { buttonRef.current = document.getElementById('btn-external'); }, []); function focusExternalButton() { buttonRef.current.focus(); }; return ( <div> <ExternalButtonComponent label="This is a button" /> <button type='button' onClick={focusExternalButton}>submit</button> </div> ); } function ExternalButtonComponent({label}) { return <div><button id="btn-external">{label}</button></div>; } ReactDOM.render( <App />, document.getElementById("root") );
 #btn-external:focus { box-shadow: 0 0 0 3px rgba(21, 156, 228, 0.4);}
 <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"></div>

但是,为了避免每次使用组件时都必须这样做,您可以包装外部组件并转发 ref

const WrappedExternalButtonComponent = forwardRef((props, ref) => {
  useEffect(() => {
    ref.current = document.getElementById('btn-external');
  }, []);

  return <ExternalButtonComponent {...props} />
});

 const { useEffect, useRef, forwardRef } = React; const WrappedExternalButtonComponent = forwardRef((props, ref) => { useEffect(() => { ref.current = document.getElementById('btn-external'); }, []); return <ExternalButtonComponent {...props} /> }); function ExternalButtonComponent({label}) { return <div><button id="btn-external">{label}</button></div>; } function App() { const buttonRef = useRef(); function focusExternalButton() { buttonRef.current.focus(); }; return ( <div> <WrappedExternalButtonComponent ref={buttonRef} label="This is a button" /> <button type='button' onClick={focusExternalButton}>submit</button> </div> ); } ReactDOM.render( <App />, document.getElementById('root') );
 #btn-external:focus { box-shadow: 0 0 0 3px rgba(21, 156, 228, 0.4);}
 <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"></div>

或者甚至通过创建一个实用程序来进一步概括它,该实用程序接受一个Component和一个查询 function 作为 arguments 并返回一个包装的组件。

const wrapExternalComponent = (Component, query) => forwardRef(({ children, ...props }, ref) => {
  useEffect(() => {
    ref.current = query();
  }, []);

  return (
    <Component {...props}>
      {children}
    </Component>
  );
});

const WrappedExternalButtonComponent = 
  wrapExternalComponent(ExternalButtonComponent, () => document.getElementById('btn-external'));

 const { useEffect, useRef, forwardRef } = React; const wrapExternalComponent = (Component, query) => forwardRef(({ children, ...props }, ref) => { useEffect(() => { ref.current = query(); }, []); return ( <Component {...props}> {children} </Component> ); }); function ExternalButtonComponent({label}) { return <div><button id="btn-external">{label}</button></div>; } const WrappedExternalButtonComponent = wrapExternalComponent(ExternalButtonComponent, () => document.getElementById('btn-external')); function App() { const buttonRef = useRef(); function focusExternalButton() { buttonRef.current.focus(); }; return ( <div> <WrappedExternalButtonComponent ref={buttonRef} label="This is a button" /> <button type='button' onClick={focusExternalButton}>submit</button> </div> ); } ReactDOM.render( <App />, document.getElementById('root') );
 #btn-external:focus { box-shadow: 0 0 0 3px rgba(21, 156, 228, 0.4);}
 <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"></div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM