高阶组件和ref
HOC 高阶组件
HOF:Higher-Order Function,高阶函数,以函数作为一个参数,返回一个参数
HOC:Higher-Order Component,高阶组件,以组件作为参数,返回一个组件
可以使用组件实现横切关注点。
注意
- 不要在render中使用高阶组件
- 不要在高阶组件中更改传入的组件
HocTestA
1 2 3 4 5 6 7 8 9 10
| import React, { Component } from 'react'
export default class HocTestA extends Component { render() { return ( <div>HocTestA</div> ) } }
|
HocTestB
1 2 3 4 5 6 7 8 9
| import React, { Component } from 'react'
export default class HocTestB extends Component { render() { return ( <div>HocTestB</div> ) } }
|
WithTestHoc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import React from "react";
export default function WithTest(Comp){ return class WithTestWrapper extends React.Component{ componentDidMount(){ console.log(`组件${Comp.name}被创建`); } render(){ return <> <Comp {...this.props}></Comp> </> } } }
|
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import React, { Component } from "react"; import WithTest from "./HOC/WithTestHoc"; import HocTestA from "./components/HocTestA"; import HocTestB from "./components/HocTestB";
const TestA = WithTest(HocTestA); const TestB = WithTest(HocTestB) export default class App extends Component { render() { return ( <> <TestA></TestA> <TestB></TestB> </> ) } }
|
reference:引用
直接使用dom中的某个方法,或使用组件中的某个方法。
- ref作用于内置的html组件,得到的将是真是的dom对象
- ref作用于类组件,将得到类的实例
- ref不能直接作用于函数组件,函数组件内部可以正常使用
ref不推荐使用字串符赋值,推荐使用函数或对象
字符串 要删除的使用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import React, { Component } from "react";
export default class Ref extends Component { onHandleClick = ()=>{ console.log(this.refs.text.value) } render() { return ( <> <input ref="text" type="text" /> <button onClick={this.onHandleClick}>获取input的值</button> </> ); } }
|
对象
通过React.createRef函数创建
对象结构
可以通过current属性获取到引用的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import React, { Component } from "react";
export default class Ref extends Component { constructor(props){ super(props); this.input = React.createRef() } onHandleClick = ()=>{ console.log(this.input.current.value) } render() { return ( <> <input ref={this.input} type="text" /> <button onClick={this.onHandleClick}>获取input的值</button> </> ); } }
|
函数
函数的调用时间:
- componentDidMount的时候会调用该函数
- 在componentDidMount事件中可以使用ref
- 如果ref的值发生了变动(旧的函数被新的函数替代),分别调用旧的函数和新的函数,时间点出现在componentDidUpdate之前
- 旧的函数被调用时,传递参数为null
- 新的函数被调用时,传递参数为引用对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import React, { Component } from "react";
export default class Ref extends Component { constructor(props){ super(props); this.input = React.createRef() } onHandleClick = ()=>{ console.log(this.input.value) } render() { return ( <> <input ref={el=>this.input = el} type="text" /> <button onClick={this.onHandleClick}>获取input的值</button> </> ); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import React, { Component } from "react";
export default class Ref extends Component { constructor(props){ super(props); this.input = React.createRef() } onHandleClick = ()=>{ console.log(this.input.value) }
getRef = (el)=>{ this.input = el } render() { return ( <> <input ref={this.getRef} type="text" /> <button onClick={this.onHandleClick}>获取input的值</button> </> ); }
|
forwardRef:
- 参数:传递的只能是函数组件,不能是类组件,函数组件要有第二个参数来得到ref
- 返回值:返回一个新的组件
高阶组件 WithTest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import React, { Component } from "react";
export default function WithTest(Comp) { class WithTest extends Component { render() { const { forwardRef, ...rest } = this.props; return <Comp ref={forwardRef} {...rest}></Comp>; } }
return React.forwardRef((props,ref)=>{ return <WithTest {...props} forwardRef={ref}></WithTest> }) }
|
组件CompA
1 2 3 4 5 6 7 8 9 10 11 12 13
| import React, { Component } from 'react' import WithTest from './WithTest'
class CompA extends Component { render() { return ( <div>CompA <h1> {this.props.data}</h1> </div> ) } } export default WithTest(CompA)
|
测试组件
1 2 3 4 5 6 7 8 9 10 11 12 13
| import React, { Component } from 'react' import CompA from './CompA' export default class Test extends Component { compARef = React.createRef(); componentDidMount(){ console.log(this.compARef); } render() { return ( <CompA data="123456" ref={this.compARef}></CompA> ) } }
|