[英]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.