亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

React ref的使用案例

發布時間:2021-04-09 10:49:52 來源:億速云 閱讀:189 作者:啵贊 欄目:開發技術

本篇內容主要講解“React ref的使用案例”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“React ref的使用案例”吧!

什么是 ref

官網介紹:

在典型的 React 數據流中,props 是父組件與子組件交互的唯一方式。要修改一個子組件,你需要使用新的 props 來重新渲染它。但是,在某些情況下,你需要在典型數據流之外強制修改子組件。被修改的子組件可能是一個 React 組件的實例,也可能是一個 DOM 元素。對于這兩種情況,React 都提供了解決辦法,即使用 ref 來獲取 dom 或組件實例。

如何使用 ref

放在 dom 元素上

這是 ref 最直接的用法

export class Demo extends React.Component {
  constructor(props) {
    super(props)
    this.myRef = createRef()
  }
  componentDidMount() {
    console.log(this.myRef)
  }
  render() {
    return <div ref={this.myRef}>測試</div>
  }
}

打印看一下 ref 是啥

React ref的使用案例

可以看出,ref.current 拿到了 dom 元素,所以我們可以實現 dom 元素本身的一些功能,如 input 的聚焦:

export class Demo extends React.Component {
  constructor(props) {
    super(props)
    this.myRef = createRef()
  }

  onClick = () => {
    this.myRef.current.focus()
  }

  render() {
    return (
      <div>
        <button onClick={this.onClick}>聚焦</button>
        <input ref={this.myRef} />
      </div>
    )
  }
}

官網還提供了一種 ref 回調的形式:

export class Demo extends React.Component {
  constructor(props) {
    super(props)
    this.myRef = null
  }

  onClick = () => {
    this.myRef.focus()
  }

  render() {
    return (
      <div>
        <button onClick={this.onClick}>聚焦</button>
        <input ref={ele => this.myRef = ele} /> // 這里的 ele 就是該 dom 元素
      </div>
    )
  }
}

放在類組件上

其實組件跟原生 dom 差不多,也是擁有自己的 ui、一些功能的某種元素,所以將 ref 放在組件上,也可以獲取到該組件的示例。

// 子組件
class Child extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      name: 'xx'
    }
  }
  render() {
    return <div>子元素{this.state.name}</div>
  }
}

export class Demo extends React.Component {
  constructor(props) {
    super(props)
    this.myRef = createRef()
  }

  componentDidMount() {
    console.log(this.myRef)
  }

  render() {
    return (
     <Child ref={this.myRef} />
    )
  }
}

React ref的使用案例

那既然可以獲取到子組件的實例,我們就可以操作子組件了,比如文章最開始說,我想在父組件里去撈子組件的某些狀態值。

class Child extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      count: 0
    }
  }
  
  onClick = () => {
    this.setState({count: this.state.count+1})
  }

  render() {
    return <button onClick={this.onClick}>點擊+1:{this.state.count}</button>
  }
}

export class Demo extends React.Component {
  constructor(props) {
    super(props)
    this.myRef = createRef()
  }

  onClick = () => {
    console.log(this.myRef.current.state.count) // 拿到子組件的狀態值
  }


  render() {
    return (
      <div>
        <button onClick={this.onClick}>獲取子組件的點擊次數</button>
        <Child ref={this.myRef} /> // ref 獲取到子組件實例
      </div>
    )
  }
}

既然能拿值,我也能拿函數去修改子組件

class Child extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      name: 'xx'
    }
  }
  changeName = () => {
    this.setState({name: 'ww'})
  }
  render() {
    return <div>子元素{this.state.name}</div>
  }
}

export class Demo extends React.Component {
  constructor(props) {
    super(props)
    this.myRef = createRef()
  }

  onClick = () => {
    this.myRef.current.changeName() // 父組件的手伸到子組件里去啦
  }

  render() {
    return (
      <div>
        <button onClick={this.onClick}>改變子組件的狀態</button>
        <Child ref={this.myRef} />
      </div>
    )
  }
}

當然這個例子并不恰當,父組件想更改子組件的狀態的話,應該把狀態提升到父組件中,然后作為子組件的props傳遞進去。
主要是 ref 提供一種方式去繞過 props 來實現父子組件通信。

放在函數組件上

這是我文章開頭寫需求時犯的錯,ref 不能放在函數組件上,因為函數組件沒有實例。

const Child = () => {
  return <div>子組件</div>
}

export const Demo = () => {
  const myRef = useRef() // 可以在函數組件內創建 ref

  useEffect(() => {
    console.log(myRef)
  }, [])

  return <Child ref={myRef} /> // 但是放在函數組件上無效
}

React ref的使用案例

那函數組件就不能使用 ref 了嗎,那肯定不是哈哈。我們可以使用 forwardRef 包裝函數組件。

const Child = (props, ref) => { // 包裝后,除了原有的 props 外, ref 也被傳了進來
  return <div ref={ref}>子組件</div> // 還是得掛載到 dom 上
}

const ProChild = React.forwardRef(Child) // 重點在這里

export const Demo = () => {
  const myRef = useRef()

  useEffect(() => {
    console.log(myRef)
  }, [])

  return <ProChild ref={myRef} />
}

React ref的使用案例

這里貼一下官網的 tip:

React ref的使用案例

那既然函數組件也可以使用 ref 的話,我們用函數組件實現一下父組件撈子組件的數據,不過可以看出,使用 forwardRef 包裹后,ref 還是得掛載到 dom 或者類組件上,如果我只想掛載數據還需要搭配 useImperativeHandle。

const Child = (props, ref) => {
  const [count, setCount] = useState(0)

  useImperativeHandle(
    ref,
    () => ({   // 這里就是暴露給外部 ref 的數據
      getVal: ()=> count
    }),
    [count],
  )

  const onClick = () => {
    setCount(pre => pre+1)
  }
  return <button onClick={onClick}>點擊+1:{count}</button>
}

const ProChild = React.forwardRef(Child)

export const Demo = () => {
  const myRef = useRef()

  const onClick = () => {
    console.log(myRef.current.getVal()) // 拿到子組件的值
  }

  return <><button onClick={onClick}>獲取子組件的點擊次數</button><ProChild ref={myRef} /></>
}

至此完成了做需求時留下的問題 ?

總結

最后還是需要強調一下,父組件獲取子組件狀態的場景,一般還是狀態提升 + 回調來通信,需求最終也是使用這種方式來實現的,最開始之所以想用 ref,是覺得狀態提升后,子組件變化了會引起父組件的重新渲染,但是我只想拿數據而不引起渲染。
跟師傅說了一下我寫需求時的想法,師傅見解如下:

  • 優先考慮狀態提升

  • 有性能問題的話,考慮狀態提升 + memo

  • 不想給多個組件加 memo 的話,就要考慮引入 redux/mobx 了

  • 如果引入 redux/mobx 是一種成本的話,那 ref 也不是不可以哈哈哈

到此,相信大家對“React ref的使用案例”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武汉市| 磐安县| 丘北县| 黑河市| 牟定县| 富民县| 濮阳县| 兰西县| 罗平县| 洛宁县| 郧西县| 鄂托克旗| 凌源市| 台北市| 长顺县| 榆林市| 泉州市| 杂多县| 隆化县| 霍城县| 高唐县| 攀枝花市| 镶黄旗| 韶关市| 万安县| 台前县| 瑞金市| 杭州市| 葫芦岛市| 原阳县| 浠水县| 霞浦县| 古交市| 邳州市| 安国市| 西昌市| 佳木斯市| 鄢陵县| 广安市| 岑溪市| 巴林左旗|