Material UI中withTheme()导致ref无法获取组件实例的解决方法
解决withTheme包裹组件后无法获取底层组件ref的问题
当然有办法搞定这个问题!当你用withTheme()这个高阶组件(HOC)包裹自己的组件后,默认情况下ref会指向HOC生成的新组件实例,而不是你原本的Widget组件,这就导致你没法直接调用example()这类原始组件的方法。下面给你两种实用的解决方案:
方案一:用React.forwardRef转发ref(推荐)
React自带的forwardRef就是专门用来解决这类HOC透传ref的问题的。你只需要稍微调整组件的定义,让它接收并转发ref:
import React, { forwardRef } from 'react'; import { withTheme } from '@material-ui/core/styles'; // 用forwardRef包裹组件,让它接收props和ref两个参数 const Widget = forwardRef((props, ref) => { // 把ref绑定到组件的根元素或者组件实例上 return <div ref={ref}>这里是Widget的内容</div>; }); // 再用withTheme包裹处理后的组件 export default withTheme()(Widget);
之后在父组件里使用ref时,就能直接拿到Widget的实例了:
<Widget ref={r => this.mywidget = r} /> <OtherWidget onClick={() => this.mywidget.example()} />
方案二:利用Material UI的innerRef属性
Material UI的withTheme其实内置了innerRef属性,可以帮你把ref传递到底层组件。你需要先让原始组件接收这个属性并绑定:
import React from 'react'; import { withTheme } from '@material-ui/core/styles'; class Widget extends React.PureComponent { example() { console.log('调用了Widget的example方法'); } render() { // 将innerRef绑定到组件实例 return <div ref={this.props.innerRef}>Widget内容</div>; } } export default withTheme()(Widget);
然后在父组件中使用innerRef代替原来的ref:
<Widget innerRef={r => this.mywidget = r} /> <OtherWidget onClick={() => this.mywidget.example()} />
问题根源小解释
高阶组件的本质是一个返回新组件的函数,当你给HOC返回的组件加ref时,这个ref自然会指向HOC创建的那个中间组件,而不是你写的原始组件。上面两种方案都是通过“透传”的方式,把ref传递到真正的底层组件上,这样你就能像没使用withTheme时一样访问组件的方法和属性了。
内容的提问来源于stack exchange,提问作者Malvineous
相关产品推荐
相关产品推荐

