Javascript 为什么DOM方法的行为在函数中是不确定的,这使得元素在React中是不确定的?

Javascript 为什么DOM方法的行为在函数中是不确定的,这使得元素在React中是不确定的?,javascript,html,reactjs,dom,Javascript,Html,Reactjs,Dom,我只是尝试使用诸如getElementsByCassName、getElementsByTagName、getElementById之类的文档方法,并对输出进行处理。然而奇怪的是,只有getElementById不工作,它记录为null。我试过使用应用程序和标记名h1的className,效果非常好。有人能解释一下吗? 这是代码沙盒[] 下面是我正在渲染的应用程序代码 function App() { { console.log(document.getElementById('headi

我只是尝试使用诸如getElementsByCassName、getElementsByTagName、getElementById之类的文档方法,并对输出进行处理。然而奇怪的是,只有getElementById不工作,它记录为null。我试过使用应用程序和标记名h1的className,效果非常好。有人能解释一下吗? 这是代码沙盒[]

下面是我正在渲染的应用程序代码

function App() {

  { console.log(document.getElementById('heading1')) }

  /*
  { console.log(document.getElementsByTagName("h1")) }
  // Output: HtmlCollection array which contains element with id=heading1
  */

  /*
  { console.log(document.getElementsByClassName("App")) }
  // Output: HtmlCollection array which contains div.App element
  */

  return (
    <div  className="App">
      <h1 id="heading1">Hello CodeSandbox</h1>

      <h2>Start editing to see some magic happen!</h2>

    </div>
  );

}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

PS编辑:。多亏了Jonas。

调用getElementById时DOM节点不可用

一个简单的解决方案是将组件转换为类组件,并使用componentDidMount生命周期方法

class App extends React.Component {
   componentDidMount() {
       console.log(document.getElementById('heading1'))
   }
   render() {
      return (
        <div  className="App">
          <h1 id="heading1">Hello CodeSandbox</h1>

          <h2>Start editing to see some magic happen!</h2>

        </div>
      );
   }
}

如果您严格想要功能组件,那么有一个库允许访问功能组件内部的生命周期方法,称为

这些方法返回两种不同的数据结构,一种是节点列表,另一种是单个节点。节点列表的特殊之处在于它们是活动的,这意味着如果一个节点被添加到DOM中,它也会被添加到节点列表中。在控制台中,您可以看到记录内容的实时版本,因此您还可以使用getElementsByTagName看到DOM中尚未包含的元素,并且使用getElementByID不会得到任何结果


然而,在使用React时,您根本不应该使用它们。

在您运行选择时,React尚未呈现组件,因此DOM中没有任何匹配标题1。那么它如何适用于标记名和类名呢?我真的不知道-AFAIK,这应该是因为渲染函数的异步行为吗?@RohanBüchner我只是想知道为什么它会这样。请检查问题的注释啊,我知道我不应该使用。我只是在尝试不同的东西。你能提供一些参考资料让它了解更多吗?我不知道那件事。谢谢你,退伍军人不一定是活着的。通常,像getElementsByTagName和childNodes中的旧节点列表是活动的,但是document.querySelectorAll中的新节点列表是静态的。我也没有主动意识到发生了什么事情,我只是想当然地/从来没有研究过这些事情。但这里有一个有趣的想象。如果您查看示例的这个分支中的两组日志。您将看到第一个集合,正如@Vivek所看到的,数组是空的,直到您在控制台中展开它。在展开时,控制台确实显示与此节点列表行为相关的元素,第二个日志集合按您的预期打印输出,因为此时,React已更新了DOM。@RobG true。仅供参考,