HsuMoonHao HsuMoonHao
首页
  • 前端文章

    • JavaScript
    • 数据结构与算法
  • vue3相关

    • 《JavaScript教程》
GitHub (opens new window)

HsyMoonHao

前端界的小学生
首页
  • 前端文章

    • JavaScript
    • 数据结构与算法
  • vue3相关

    • 《JavaScript教程》
GitHub (opens new window)
  • 前端-设计模式

  • js数据结构与算法

  • js程序设计

  • vue3相关

  • 微前端

  • react

    • ref
      • 使用方式
        • class组件
        • function组件
      • 使用场景
      • 其他使用
    • react中的生命周期函数
    • 对SPA的理解
  • 前端
  • react
HsyMoonHao
2023-05-20
目录

ref

# Ref

定义:当你希望组件“记住”某些信息,但又不想让这些信息 触发新的渲染 时,你可以使用 ref 。

# 使用方式

# class组件

  • 过时的string类型

    class Demo extends React.Component{
        testRef = ()=>{
            console.log(this.refs.inputRef.value)
        }
        render (){
            return (
                <>
                	<h1>Hello, <b>React</b> world!</h1>
                	<input ref="inputRef" pleaseholder="请输入的内容" />
    	            <br />
    	            <button onClick={this.testRef}>test</button>
                </>
            )
        }
    }
    ReactDOM.render(<Demo />, document.getElementById('root'));
    /**
    	Warning: ReactDOM.render is no longer supported in React 18.
    	Use createRoot instead. Until you switch to the new API,
    */
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
  • 回调ref类型

     class Demo extends React.Component{
         InputRef = null;
         testRef = ()=>{
             console.log(this.inputRef.value)
         }
         /** 用于解决内联绑定式的回调在更新state的过程中,执行两次的问题*/
    	 saveInputRef(e){
    		this.InputRef = e
         }
         render (){
             return (
                 <>
                 	<h1>Hello, <b>React</b> world!</h1>
                 	{/** 回调类型的ref,会在更新过程中执行两次,但是并不会对业务造成影响, 第一次会返回一个null,第二次才会返回绑定的DOM节点 */}
                 	<input ref={ e => this.inputRef = e } pleaseholder="请输入的内容" />
                 	{/** 用于解决内联绑定式的回调在更新state的过程中,执行两次的问题 */}
                 	<input ref={ this.saveInputRef } pleaseholder="请输入的内容" />
                 	<br />
                 	<button onClick={this.testRef}>test</button>
                 </>
             )
         }
    }
    ReactDOM.render(<Demo />, document.getElementById('root'));
    /**
    	Warning: ReactDOM.render is no longer supported in React 18.
    	Use createRoot instead. Until you switch to the new API,
    */
    
    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
  • createRef类型

    class Demo extends React.Component{
        inputRef = React.createRef()
    	testRef = ()=>{
        	console.log(this.inputRef.current.value)
    	}
        render (){  
            return (
    	        <>
            		<h1>Hello, <b>React</b> world!</h1>
    		        <input ref={this.inputRef} pleaseholder="请输入的内容" />
            		<br />
            		<button onClick={this.testRef}>test</button>
            	</>
        	)
    	}
    }
    ReactDOM.render(<Demo />, document.getElementById('root'));
    /**
    	Warning: ReactDOM.render is no longer supported in React 18.
    	Use createRoot instead. Until you switch to the new API,
    */
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

# function组件

/** React 18.*/
import { useRef } from "react"
function MyApp() {
     const inputRef = useRef(null)
     const testRef = ()=>{
         console.log(inputRef.current.value)
     }
     return (
         <>
         	<h1>Hello, <b>React</b> world!</h1>
         	<input ref={inputRef} pleaseholder="请输入的内容" />
         	<br />
         	<button onClick={testRef}>test</button>
         </>
     )
 }
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<MyApp />)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 使用场景

  • 存储 timeout ID;

    import { useState, useRef } from 'react';
    
    export default function Stopwatch() {
      const [startTime, setStartTime] = useState(null);
      const [now, setNow] = useState(null);
      const intervalRef = useRef(null);
    
      function handleStart() {
        setStartTime(Date.now());
        setNow(Date.now());
    
        clearInterval(intervalRef.current);
        intervalRef.current = setInterval(() => {
          setNow(Date.now());
        }, 10);
      }
    
      function handleStop() {
        clearInterval(intervalRef.current);
      }
    
      let secondsPassed = 0;
      if (startTime != null && now != null) {
        secondsPassed = (now - startTime) / 1000;
      }
    
      return (
        <>
          <h1>时间过去了: {secondsPassed.toFixed(3)}</h1>
          <button onClick={handleStart}>
            开始
          </button>
          <button onClick={handleStop}>
            停止
          </button>
        </>
      );
    }
    
    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
    38
  • 存储和操作 DOM 元素;

    // 如上为input绑定ref
    
    1
  • 存储不需要被用来计算 JSX 的其他对象。

    // 后续补充
    
    1

# 其他使用

访问另一个组件的 DOM 节点 ,因为默认情况下,React 不允许组件访问其他组件的 DOM 节点。甚至自己的子组件也不行!

/**
	<MyInput ref={inputRef} /> 告诉 React 将对应的 DOM 节点放入 inputRef.current 中。
	但是,这取决于 MyInput 组件是否允许这种行为, 默认情况下是不允许的。
	MyInput 组件是使用 forwardRef 声明的。 这让从上面接收的 inputRef 作为第二个参数 ref 传入组件,第一个参数是 props 。
	MyInput 组件将自己接收到的 ref 传递给它内部的 <input>。
*/
import { forwardRef, useRef } from 'react';

const MyInput = forwardRef((props, ref) => {
  return <input {...props} ref={ref} />;
});

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <MyInput ref={inputRef} />
      <button onClick={handleClick}>
        聚焦输入框
      </button>
    </>
  );
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<MyInput />)
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
编辑 (opens new window)
上次更新: 2023/05/21, 23:27:23
初识乾坤
react中的生命周期函数

← 初识乾坤 react中的生命周期函数→

最近更新
01
Async和Defer
01-03
02
typescript utils
12-23
03
对SPA的理解
05-29
更多文章>
Theme by Vdoing | Copyright © 2023-2024 HsyMoonHao | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式