The use of ref in React

Posted by Aebx on Tue, 14 Apr 2020 16:01:49 +0200

Example: get the distance from the button element to the top of the page

ref is written on html elements

import React,{Component,Fragment} from 'react';
import Child from './Child';

class Counter extends Component{

    constructor(props){
        super(props);
        this.addCount=this.addCount.bind(this);

        this.state={
            counter:1
        }
    }

    addCount(){
        console.log(this.button);
        console.log(this.button.clientTop);

        this.setState({
            counter:this.state.counter+1
        })
    }

    render(){
        return(
            <Fragment>
                <button onClick={this.addCount} ref={button=>this.button=button}>click</button>
                <Child num={this.state.counter}/>
            </Fragment>
        )
    }
}

export default Counter;

 

 

ref is written on the component. It gets the instance of the component

import React,{Component,Fragment} from 'react';
import Child from './Child';

class Counter extends Component{

    constructor(props){
        super(props);
        this.addCount=this.addCount.bind(this);

        this.state={
            counter:1
        }
    }

    addCount(){
        console.log(this.child);

        this.setState({
            counter:this.state.counter+1
        })
    }

    render(){
        return(
            <Fragment>
                <button onClick={this.addCount}>click</button>
                <Child num={this.state.counter} ref={child=>this.child=child}/>
            </Fragment>
        )
    }
}

export default Counter;

 

 

Conclusion: ref is written on the html tag, and the DOM node is obtained

ref is written on the component tag to get the JS instance of the component

 

setState asynchronous, instance:

import React,{Component,Fragment} from 'react';

class Counter extends Component{

    constructor(props){
        super(props);
        this.addCount=this.addCount.bind(this);

        this.state={
            counter:1
        }
    }

    addCount(){
        console.log(this.div.innerHTML);

        this.setState({
            counter:this.state.counter+1
        })

        console.log(this.div.innerHTML);
    }

    render(){
        return(
            <Fragment>
                <button onClick={this.addCount}>click</button>
                <div ref={div=>this.div=div}>{this.state.counter}</div>
            </Fragment>
        )
    }
}

export default Counter;

 

 

You can see that the output of both times is 1, which proves that the setState operation is performed asynchronously

 

resolvent:

import React,{Component,Fragment} from 'react';

class Counter extends Component{

    constructor(props){
        super(props);
        this.addCount=this.addCount.bind(this);

        this.state={
            counter:1
        }
    }

    addCount(){
        console.log(this.div.innerHTML);

        this.setState(()=>{
            return{
                counter:this.state.counter+1
            }
        },()=>{
            console.log(this.div.innerHTML);
        })
    }

    render(){
        return(
            <Fragment>
                <button onClick={this.addCount}>click</button>
                <div ref={div=>this.div=div}>{this.state.counter}</div>
            </Fragment>
        )
    }
}

export default Counter;

In this way, the second print will be executed after setState is executed

Result:

Topics: Javascript Fragment React