如何在React中访问DOM元素? React中document.getElementById()的等价是什么

时间:2016-06-29 08:05:17

标签: javascript reactjs getelementbyid

如何在react.js中选择某些条形图?

这是我的代码:

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 (...);
    }

我想使用这个React组件:

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>
        )
    }
});

我想执行handleClick10函数并执行所选进度条的操作。 但我得到的结果是:

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

如何选择react.js中的某个元素?

8 个答案:

答案 0 :(得分:127)

您可以通过指定ref

来实现
<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"/>

为了获得元素

var object = this.refs.Progress1;

请记住在箭头功能块中使用this,如:

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

依旧......

修改

然而,facebook建议反对它,因为字符串引用有一些问题,被认为是遗留问题,很可能会在未来的某个版本中删除。

来自文档:

  

旧版API:字符串参考

     

如果您之前使用过React,那么您可能会   熟悉旧的API,其中ref属性是一个字符串,如   “textInput”,DOM节点作为this.refs.textInput访问。我们   建议反对它,因为字符串引用有一些问题,考虑   遗留问题,很可能会在未来的某个版本中删除。如果   你现在正在使用this.refs.textInput来访问refs,我们   建议使用回调模式。

React 16.2及更早版本的推荐方法是使用回调模式:

<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

React 16.3 + 中,使用React.createRef()创建您的参考:

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

要访问该元素,请使用:

const node = this.myRef.current;

DOC for using React.createRef()

答案 1 :(得分:21)

要获取react中的元素,您需要使用ref并在函数内部使用ReactDOM.findDOMNode方法。

但我喜欢做的更多是在事件中调用ref

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

这是一个很好的链接,可以帮助你弄明白。

https://facebook.github.io/react/docs/refs-and-the-dom.html

答案 2 :(得分:6)

在较新版本的 React 中,您可以通过像这样的钩子来使用和操作 DOM:

import React, { useEffect, useRef } from "react";

const MyComponent = () => {
  const myContainer = useRef(null);
  
  useEffect(() => {
    console.log("myContainer..", myContainer.current);
  });

  return (
    <>
      <h1>Ref with react</h1>
      <div ref={myContainer}>I can use the DOM with react ref</div>
    </>
  );
};

export default MyComponent;

每当您想访问 DOM 元素时,只需使用 myContainer

答案 3 :(得分:4)

您可以替换

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

通过

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


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

答案 4 :(得分:2)

免责声明:虽然最佳答案可能是一个更好的解决方案,但作为初学者,当您想要的只是一些非常简单的东西时,需要做很多事情。这是对您的原始问题“如何在 React 中选择某些元素”的更直接回答

我认为您的问题中的混淆是因为您有 React component 正在向您传递 ID“Progress1”、“Progress2”等。我相信这不是设置 html 属性 ' id',而是 React 组件属性。例如

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

正如上面的一些答案中提到的,您绝对可以在 React 应用程序中使用 document.querySelector,但您必须清楚它正在选择组件渲染方法的 html 输出。因此,假设您的渲染输出如下所示:

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

然后你可以在其他地方做一个普通的 javascript querySelector 调用,如下所示:

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

答案 5 :(得分:1)

由于React使用JSX代码创建HTML,因此我们无法使用documment.querySelector或getElementById等调节方法来引用dom。

相反,我们可以使用React ref系统访问和操作Dom,如下例所示:

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}
             />

        );

}

}

答案 6 :(得分:0)

把它放在你的输入字段

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

答案 7 :(得分:-3)

就我而言,我无法使用 ref,因为元素位于许多子组件之间,我必须通过类和 ID 而不是 ref 来访问它们。因此,尝试使用 useEffect 钩子不起作用,因为它找不到元素:

useEffect(() => {
  const el1 = document.querySelector('.el1')
  const el2 = document.querySelector('.el2')
}, [])

元素是 undefined 因为当它被挂载时,子组件也不会在这个父组件之前被挂载。

所以,我所做的是使用超时:

useEffect(() => {
  const timer = setTimeout(() => {
    const el1 = document.querySelector('.el1')
    const el2 = document.querySelector('.el2')
  },500)
  return () => {
    clearTimeout(timer)
  }
}, [])

现在,它运行良好。它找到了 DOM,我可以用它们进行操作。希望,这对某人有所帮助!