每个项目产品都要加埋点,加500行埋点是不是会占用你一两天的时间而且很容易犯错,想只用一小时准确加完这500行埋点剩下一天喝茶聊天么?来试试这520web工具, 高效加埋点,目前我们公司100号前端都在用,因为很好用,所以很自然普及开来了,推荐给大家吧
自己开发所以免费,埋点越多越能节约时间,点两下埋点就加上了,还不会犯错,里面有使用视频,反正免费 😄
React中Refs学习(二)
一月 23, 2019 by Fakin
上篇文章我们说到react中refs一些基本的知识,本篇文章我们学习refs进阶知识!这也是年前最后一篇文章了!
对父组件暴露节点
大多数情况下,我们不需要让子组件对父组件暴露DOM
,而且React
也不太支持我们这么做(尽管这是可行的),但是有些情况你又非得这么做,比如:让子组件input
自动获得焦点亦或者你必须知道子组件的位置和大小!
function children(props) {
return (
<div>
<input ref={props.inputRef} />
</div>
);
}
class Parent extends React.Component {
render() {
return (
<children
inputRef={el => this.inputElement = el}
/>
);
}
}
需要注意的是,如果你直接在子组件上添加ref
然后在父组件上获取,获取到的将会是子组件实例而不是你需要的Dom
节点,所以这时候我们需要在子组件上暴露一个特殊的属性,然后让父组件获取。
回调refs
在上一篇中有说到函数式组件无法使用ref
,但是你可以在函数式组件内部使用ref
,这个时候ref
必须指向Dom
元素或者class
。这是也就是回调了。
函数式组件内部使用ref
function Fakin(props) {
// 这里必须声明 textInput,这样 ref 回调才可以引用它
let textInput = null;
function handleClick() {
textInput.focus();
}
return (
<div>
<input
type="text"
ref={(input) => { textInput = input; }} />
<input
type="button"
value="Focus the text input"
onClick={handleClick}
/>
</div>
);
}
类组件中ref
回调示例
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
this.setTextInputRef = element => {//ref回调函数
this.textInput = element;
};
this.focusTextInput = () => {
if (this.textInput) this.textInput.focus();//自动获得焦点
};
}
componentDidMount() {
this.focusTextInput();
}
render() {
return (
<div>
<input
type="text"
ref={this.setTextInputRef}
/>
</div>
);
}
}
这段代码的意思是打开页面input自动获得焦点,ref={this.setTextInputRef}
在this.setTextInputRef
中this.textInput
指向了DOM
元素(input
)。
那有人要说了,你这个用ref
回调和我直接写ref={xxx}
有什么区别啊,都可以做到相同的事情!
React
是这么描述refs
回调的
which gives more fine-grain control over when refs are set and unset.
意思是ref回调
可以对何时设置和取消引用进行更精细的控制。
在上面这段代码中,React
会在组件挂载时用DOM
元素调用ref回调
,组件卸载的时候把ref
设置为null
,从而能更加精确的控制!
高阶组件的refs
好像博主的文章还没涉及高阶组件,不管了,先简单的介绍了高阶组件吧。
高阶组件:获取一个组件并返回一个新的组件
咦,这不就是纯函数吗。
function fakin(ChildrenComponent) {
class Fakin extends React.Component {
render() {
return <ChildrenComponent {...this.props} />;
}
}
return Fakin;
}
在HOC(高阶组件中使用refs,父组件获取子组件的dom)
function fakin(Component) {
class Fakin extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props:', this.props);
}
render() {
const {forwardedRef, ...rest} = this.props;
return <Component ref={forwardedRef} {...rest} />;
}
}
return React.forwardRef((props, ref) => {
return <Fakin {...props} forwardedRef={ref} />;
});
}
在类组件Fakin
中正常返回<Component ref={forwardedRef} {...rest} />;
而且ref
书写
最后咱们使用React.forwardRef
这个方法来显示将refs转发到内部组件。否则refs
指向的是Fakin
这个HOC
补充
React.createRef()
创建ref
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}
访问refs
const myRef = this.myRef.current;
React.forwardRef
创建一个React
,同时接收一个函数作为参数,该函数有两个参数(prop,ref),该函数返回一个React节点,把两个参数(prop,ref)作为节点的(prop,ref)
const Button = React.forwardRef((props, ref) => (
<button ref={ref} className="Button">
{props.children}
</button>
));
const ref = React.createRef();
<Button ref={ref}>点击我</Button>;
这一点React不希望我们这么做,但是在HOC中有时候不得不这么做~