Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

class和hooks的ref处理 #33

Closed
keep-run opened this issue May 14, 2021 · 1 comment
Closed

class和hooks的ref处理 #33

keep-run opened this issue May 14, 2021 · 1 comment

Comments

@keep-run
Copy link
Owner

介绍

在react的日常开发过程中,ref虽然使用不多,但是却是一个非常重要的属性,可以解决很多实际问题。比如:

  • class组件中,父组件可以利用ref获取子组件的实例,从而访问子组件的状态以及方法(虽然不建议这么用,但确实有一定的使用场景);
  • 函数组件中,配合useRefuseImperativeHandle使用,可以暴露出供父组件访问的属性和方法(注意函数组件没有实例,不能通过获取实例的方式访问子组件);

下边就具体看看函数组件和class组件在使用中的区别;

class组件中的ref

import React, { Component, createRef } from 'react'
import { Button } from 'antd'

class ChildComp extends Component {
  state = {
    bgColor: 'red'
  }
  setBgColor = (bgColor) => {
    this.setState({ bgColor })
  }
  render() {
    return (<div style={{ width: '200px', height: "50px", backgroundColor: this.state.bgColor }} />)
  }
}

export default class Demo extends Component {
  constructor(props) {
    super(props)
    this.childRef = createRef()
  }
  /** 父组件中调用子组件的方法,从而改变子组件的状态 */
  setChildBgColor = (color) => {
    this.childRef.current.setBgColor(color)
  }
  render() {
    return (
      <>
        <Button onClick={() => { this.setChildBgColor('red') }}>red</Button>
        <Button onClick={() => { this.setChildBgColor('black') }}>black</Button>
        <Button onClick={() => { this.setChildBgColor('green') }}>green</Button>
        <ChildComp ref={this.childRef} />
      </>
    )
  }
}

函数组件中的ref

import React, { useRef, forwardRef, useState, useImperativeHandle } from 'react'
import { Button } from 'antd'

function Child(props, ref) {
  const [bgcolor, setBgColor] = useState('red')
  useImperativeHandle(ref, () => {
    return { setBgColor: setBgColor }   //区别在这里,手动暴露供父组件访问的属性和方法
  })
  return <div style={{ width: '200px', height: "50px", backgroundColor: bgcolor }} />
}

const ChildComp = forwardRef(Child) // 注意ref需要用forwardRef承接,不能直接从props中取

export default () => {
  const childRef = useRef(null)
  const setChildBgColor = (color) => {
    childRef.current.setBgColor(color)
  }
  return (
    <>
      <Button onClick={() => { setChildBgColor('red') }}>red</Button>
      <Button onClick={() => { setChildBgColor('black') }}>black</Button>
      <Button onClick={() => { setChildBgColor('green') }}>green</Button>
      <ChildComp ref={childRef} />
    </>
  )
}

总结

实现的功能相似,但是注意实现上的差异,见函数组件的备注。

@keep-run
Copy link
Owner Author

done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant