国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - React - React ref的使用示例

React ref的使用示例

2022-02-25 16:29陳小瓦 React

這篇文章主要介紹了React ref的使用詳解,幫助大家更好的理解和學習使用React,感興趣的朋友可以了解下

寫了一段時間的 react,99%都在寫 state、prop、useState、useEffect,對 ref 特別不熟悉,前幾天做一個需求,想用 ref 實現父組件撈子組件的某個狀態值,結果失敗了,特此整理一下 ref 相關內容。

什么是 ref

官網介紹:

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

如何使用 ref

放在 dom 元素上

這是 ref 最直接的用法

?
1
2
3
4
5
6
7
8
9
10
11
12
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 的聚焦:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 回調的形式:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 放在組件上,也可以獲取到該組件的示例。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 子組件
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的使用示例

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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>
    )
  }
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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 不能放在函數組件上,因為函數組件沒有實例。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
const Child = () => {
  return <div>子組件</div>
}
 
export const Demo = () => {
  const myRef = useRef() // 可以在函數組件內創建 ref
 
  useEffect(() => {
    console.log(myRef)
  }, [])
 
  return <Child ref={myRef} /> // 但是放在函數組件上無效
}

React ref的使用示例

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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的使用詳解的詳細內容,更多關于React ref的使用的資料請關注服務器之家其它相關文章!

原文鏈接:https://juejin.cn/post/6948422543288041503

延伸 · 閱讀

精彩推薦
  • ReactReact實現登錄表單的示例代碼

    React實現登錄表單的示例代碼

    這篇文章主要介紹了React實現登錄表單的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下...

    喬路非6832022-02-23
  • React一文幫你理解PReact10.5.13源碼

    一文幫你理解PReact10.5.13源碼

    這篇文章主要介紹了一文幫你理解PReact10.5.13源碼,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下...

    我的小樹林5432022-02-22
  • Reactreact-native 實現購物車滑動刪除效果的示例代碼

    react-native 實現購物車滑動刪除效果的示例代碼

    這篇文章主要介紹了react-native 實現購物車滑動刪除效果的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    程序猿tx3892021-12-31
  • React使用 React 和 Threejs 創建一個VR全景項目的過程詳解

    使用 React 和 Threejs 創建一個VR全景項目的過程詳解

    這篇文章主要介紹了使用 React 和 Threejs 創建一個VR全景項目的過程詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒...

    Windy Z11082022-02-23
  • React基于Vite 的組件文檔編寫神器,又快又省心

    基于Vite 的組件文檔編寫神器,又快又省心

    翻閱 Vite 的官方庫列表,偶然發現了一款 star 數量僅 100 多的文檔解決方案 vite-plugin-react-pages。開始用試試水的心態去去體驗一把,結果發現相當好用。...

    前端星辰9382021-12-27
  • ReactReactRouter的實現方法

    ReactRouter的實現方法

    這篇文章主要介紹了ReactRouter的實現,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下...

    WindrunnerMax6202022-01-06
  • ReactReact.Children的用法詳解

    React.Children的用法詳解

    這篇文章主要介紹了React.Children的用法詳解,幫助大家更好的理解和學習使用React框架,感興趣的朋友可以了解下...

    uuihoo10672022-02-23
  • ReactReact中setState的使用與同步異步的使用

    React中setState的使用與同步異步的使用

    這篇文章主要介紹了React中setState的使用與同步異步的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋...

    一顆冰淇淋5232022-02-17
主站蜘蛛池模板: 亚洲国产色视频 | 天天操一操 | 全部古装三级在线播放 | 久草福利资源 | 福利一区二区 | 91网在线观看 | 深夜视频在线观看 | 久久一级黄 | av在线免费观看一区二区 | av中文字幕在线观看 | 午夜影院在线 | 在线永久免费观看日韩a | 午夜视频在线播放 | 国产成人精品一区二区 | 中文字幕精品一区二区三区精品 | 国产片在线观看免费观看 | 这里只有国产精品 | 成人av观看 | 99中文字幕 | 午夜激情在线播放 | 国产精品视频播放 | 日韩国产 | 91精品日韩 | 精品小视频| 美女爽到呻吟久久久久 | 日韩欧美三级在线观看 | 三级视频网站 | 在线欧美 | 国产成人精品久久二区二区91 | 天天色视频| 国产毛片v一区二区三区 | 久久av资源| 久久久91精品国产一区二区三区 | 午夜精品在线 | 亚洲一区在线日韩在线深爱 | 亚洲一区中文字幕在线观看 | 精品成人免费一区二区在线播放 | 国产专区在线看 | 国产精品午夜电影 | 欧美午夜精品久久久久久蜜 | www.欧美亚洲 |