[javascript] How to access a DOM element in React? What is the equilvalent of document.getElementById() in React

How do I select certain bars in react.js?

This is my code:

var Progressbar = React.createClass({
    getInitialState: function () {
        return { completed: this.props.completed };
    },
    addPrecent: function (value) {
        this.props.completed += value;
        this.setState({ completed: this.props.completed });
    },

    render: function () {

        var completed = this.props.completed;
        if (completed < 0) { completed = 0 };


        return (...);
    }

I want to use this React component:

var App = React.createClass({
    getInitialState: function () {

        return { baction: 'Progress1' };
    },
    handleChange: function (e) {
        var value = e.target.value;
        console.log(value);
        this.setState({ baction: value });
    },
    handleClick10: function (e) {
        console.log('You clicked: ', this.state.baction);
        document.getElementById(this.state.baction).addPrecent(10);
    },
    render: function () {
        return (
            <div class="center">Progress Bars Demo
            <Progressbar completed={25} id="Progress1" />
                <h2 class="center"></h2>
                <Progressbar completed={50} id="Progress2" />
                <h2 class="center"></h2>
                <Progressbar completed={75} id="Progress3" />
                <h2 class="center"></h2>
                <span>
                    <select name='selectbar' id='selectbar' value={this.state.baction} onChange={this.handleChange}>
                        <option value="Progress1">#Progress1</option>
                        <option value="Progress2">#Progress2</option>
                        <option value="Progress3">#Progress3</option>
                    </select>
                    <input type="button" onClick={this.handleClick10} value="+10" />
                    <button>+25</button>
                    <button>-10</button>
                    <button>-25</button>
                </span>
            </div>
        )
    }
});

I want to execute the handleClick10 function and perform the operation for my selected progressbar. But the result I get is:

 You clicked:  Progress1
 TypeError: document.getElementById(...) is null

How do I select the certain Element in react.js?

This question is related to javascript reactjs getelementbyid

The answer is


You can do that by specifying the ref

EDIT: In react v16.8.0 with function component, you can define a ref with useRef. Note that when you specify a ref on a function component, you need to use React.forwardRef on it to forward the ref to the DOM element of use useImperativeHandle to to expose certain functions from within the function component

Ex:

const Child1 = React.forwardRef((props, ref) => {
    return <div ref={ref}>Child1</div> 
});

const Child2 = React.forwardRef((props, ref) => {
    const handleClick= () =>{};
    useImperativeHandle(ref,() => ({
       handleClick
    }))
    return <div>Child2</div> 
});
const App = () => {
    const child1 = useRef(null);
    const child2 = useRef(null);

    return (
        <>
           <Child1 ref={child1} />
           <Child1 ref={child1} />
        </>
    )
}

EDIT:

In React 16.3+, use React.createRef() to create your ref:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

In order to access the element, use:

const node = this.myRef.current;

DOC for using React.createRef()


EDIT

However facebook advises against it because string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases.

From the docs:

Legacy API: String Refs

If you worked with React before, you might be familiar with an older API where the ref attribute is a string, like "textInput", and the DOM node is accessed as this.refs.textInput. We advise against it because string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases. If you're currently using this.refs.textInput to access refs, we recommend the callback pattern instead.

A recommended way for React 16.2 and earlier is to use the callback pattern:

<Progressbar completed={25} id="Progress1" ref={(input) => {this.Progress[0] = input }}/>

<h2 class="center"></h2>

<Progressbar completed={50} id="Progress2" ref={(input) => {this.Progress[1] = input }}/>

  <h2 class="center"></h2>

<Progressbar completed={75} id="Progress3" ref={(input) => {this.Progress[2] = input }}/>

DOC for using callback


Even older versions of react defined refs using string like below

<Progressbar completed={25} id="Progress1" ref="Progress1"/>

    <h2 class="center"></h2>

    <Progressbar completed={50} id="Progress2" ref="Progress2"/>

      <h2 class="center"></h2>

    <Progressbar completed={75} id="Progress3" ref="Progress3"/>

In order to get the element just do

var object = this.refs.Progress1;

Remember to use this inside an arrow function block like:

print = () => {
  var object = this.refs.Progress1;  
}

and so on...


You can replace

document.getElementById(this.state.baction).addPrecent(10);

with

this.refs[this.state.baction].addPrecent(10);


  <Progressbar completed={25} ref="Progress1" id="Progress1"/>

Disclaimer: While the top answer is probably a better solution, as a beginner it's a lot to take in when all you want is something very simple. This is intended as a more direct answer to your original question "How can I select certain elements in React"

I think the confusion in your question is because you have React components which you are being passed the id "Progress1", "Progress2" etc. I believe this is not setting the html attribute 'id', but the React component property. e.g.

class ProgressBar extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            id: this.props.id    <--- ID set from <ProgressBar id="Progress1"/>
        }
    }        
}

As mentioned in some of the answers above you absolutely can use document.querySelector inside of your React app, but you have to be clear that it is selecting the html output of your components' render methods. So assuming your render output looks like this:

render () {
    const id = this.state.id
    return (<div id={"progress-bar-" + id}></div>)
}

Then you can elsewhere do a normal javascript querySelector call like this:

let element = document.querySelector('#progress-bar-Progress1')

put it your input field

ref={(el) => this.myInput = el}

For getting the element in react you need to use ref and inside the function you can use the ReactDOM.findDOMNode method.

But what I like to do more is to call the ref right inside the event

<input type="text" ref={ref => this.myTextInput = ref} />

This is some good link to help you figure out.


Since React uses JSX code to create an HTML we cannot refer dom using regulation methods like documment.querySelector or getElementById.

Instead we can use React ref system to access and manipulate Dom as shown in below example:

constructor(props){

    super(props);
    this.imageRef = React.createRef(); // create react ref
}

componentDidMount(){

    **console.log(this.imageRef)** // acessing the attributes of img tag when dom loads
}


render = (props) => {

const {urls,description} = this.props.image;
    return (

            <img
             **ref = {this.imageRef} // assign the ref of img tag here**
             src = {urls.regular} 
             alt = {description}
             />

        );

}

}


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to reactjs

Error: Node Sass version 5.0.0 is incompatible with ^4.0.0 TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined raised when starting react app Template not provided using create-react-app How to resolve the error on 'react-native start' Element implicitly has an 'any' type because expression of type 'string' can't be used to index Invalid hook call. Hooks can only be called inside of the body of a function component How to style components using makeStyles and still have lifecycle methods in Material UI? React Hook "useState" is called in function "app" which is neither a React function component or a custom React Hook function How to fix missing dependency warning when using useEffect React Hook? Unable to load script.Make sure you are either running a Metro server or that your bundle 'index.android.bundle' is packaged correctly for release

Examples related to getelementbyid

getElementById in React How to access a DOM element in React? What is the equilvalent of document.getElementById() in React vue.js 'document.getElementById' shorthand Cannot read property 'addEventListener' of null Onclick function based on element id Use of document.getElementById in JavaScript How to pick element inside iframe using document.getElementById It says that TypeError: document.getElementById(...) is null document.getElementById('btnid').disabled is not working in firefox and chrome Change the Value of h1 Element within a Form with JavaScript