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

IT技术 javascript reactjs getelementbyid
2021-02-03 17:51:53

如何在 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 中选择某个元素?

6个回答

您可以通过指定 ref

编辑:在带有函数组件的 react v16.8.0 中,您可以使用 useRef 定义一个 ref。请注意,当您在函数组件上指定 ref 时,您需要在其上使用 React.forwardRef 将 ref 转发到 use to 的 DOM 元素useImperativeHandle以从函数组件内部公开某些函数

前任:

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

编辑:

React 16.3+ 中,使用React.createRef()来创建你的 ref:

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

要访问该元素,请使用:

const node = this.myRef.current;

使用 React.createRef() 的文档


编辑

然而 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


甚至旧版本的 react 使用如下字符串定义了 refs

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

等等...

@akshaykishore您需要使用另一个名称(例如innerRef)将ref向下传递并将其传递给所需的组件
2021-03-15 17:51:53
Facebook 建议不要采用这种方法。请参阅此处facebook.github.io/react/docs/refs-and-the-dom.html
2021-03-21 17:51:53
@MattSidor,感谢您的编辑,您为我节省了一些时间:-)
2021-03-21 17:51:53
嗯,问题是如果我不能通过“this”访问它怎么办,比如如果我需要的组件是另一个类的实例怎么办?(即父组件中的另一个子反应组件)
2021-03-28 17:51:53
@dmitrymar 正如我所看到的,上面的页面是为 v15.4.2 以后编写的,我想,当我写答案时,这并不存在。无论如何,用正确的方法编辑了答案
2021-04-07 17:51:53

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

但我更喜欢做的是在事件内部调用 ref

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

这是一些很好的链接,可以帮助您弄清楚。

打电话React.findDOMNode给我react__WEBPACK_IMPORTED_MODULE_0___default.a.findDOMNode is not a function
2021-03-13 17:51:53
@JamesPoulose 确保您没有在严格模式下运行,因为 react 不允许您React.findDOMNode在严格模式下使用
2021-03-21 17:51:53
这是执行此操作的正确方法。这会添加对对象/类上元素的引用,您可以简单地使用它this.myTextInput来访问。
2021-04-01 17:51:53
如何使用动态创建的元素执行此操作?
2021-04-02 17:51:53

在较新版本的 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

你可以更换

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

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


  <Progressbar completed={25} ref="Progress1" id="Progress1"/>
如何使用动态创建的元素执行此操作?
2021-03-21 17:51:53

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

我认为您的问题中的混淆是因为您有 React组件,您正在传递 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"/>
        }
    }        
}

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

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

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

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