React 2020 中的 document.getElementById() 等效项

Posted

技术标签:

【中文标题】React 2020 中的 document.getElementById() 等效项【英文标题】:document.getElementById() equivalent in React 2020 【发布时间】:2020-03-29 00:42:42 【问题描述】:

我有一个名为 Button.js 的组件,它有一个按钮,当单击该按钮时,我只想知道我是否正在访问另一个名为 Timer.js 的组件中的 div。在 vanilla javascript 中,我将简单地使用 document.getElementById() 来捕获 DOM 节点。这在 React 中是如何完成的?

我在docs 中遇到了回调引用,但它不起作用。如果使用 ref 不是访问 DOM 元素的 React 方式,请向我推荐执行此操作的最佳方式。提前致谢。

Button.js

    function Button() 
    const gethtml = () => 
        const node = test.current;
        console.log(node);
    
return (
         <button onClick=getHtml>GetHtml</button>
       )

Timer.js

function Timer() 
  const test = useRef(null);
  return (
   <div ref=test>... </div>
   <Button />

【问题讨论】:

【参考方案1】:

我不会使用引用来检查一个组件是否在另一个组件中呈现。 您可以通过createContextuseContext 获得所需的内容。

(它可以像您尝试过的那样工作。如果您将 ref 作为道具传递给按钮。)

使用上下文:您在 Timer 组件中创建一个 TimerContext.Provider,在您的按钮中,您可以使用 useContext(TimerContext) 检查预期的键是否在对象中。如果它不存在,则该按钮不在您的计时器内。

请查看下面的 sn-p 或下面的Codesandbox。

//import React,  useContext, createContext  from "react";
//import "./styles.css";

const  useContext, createContext  = React;

const ContainerContext = createContext(
  isInContainer: null
);

const Container = () => 
  return (
    <ContainerContext.Provider value= isInContainer: true >
      <p>
        In container:
        <Button />
      </p>
    </ContainerContext.Provider>
  );
;

const Button = () => 
  const  isInContainer  = useContext(ContainerContext);
  console.log(isInContainer);
  const isInside = () => 
    alert(isInContainer ? "clicked inside" : "not in container");
  ;

  return <button onClick=isInside>Click me</button>;
;

function App() 
  return (
    <div className="App">
      <Container />
      <Button />
    </div>
  );


const rootElement = document.getElementById("root");
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  rootElement
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

15.04.2020 更新

起初我并不清楚这个问题,但现在我理解了这个用例。这个想法是有一个 Editor 组件,您可以在其中编写可用于生成复制的 sn-p 视图和/或 html 标记输出的标记。

为此,最好的方法是使用对 Editor 组件的引用并将其作为 prop 传递给预览/输出组件 - 也可以使用上下文,但传递它更容易。

如下Sandbox。

【讨论】:

我在不同的js文件Timer.js和Button.js中有两个组件。当我使用您的代码 ContainerContext 在 Button.js 中未定义,因为它不知道它在 Timer.js 中定义。 你可以在 Button.js 中 export const ContainerContext = ...import ContainerContext from './Timer' 感谢您的帮助,但仍然无法正常工作。我很困惑为什么 React 让原版 javascript 中如此简单的事情变得如此困难。 document.getElementById(). 所以在下面sandbox 我已经添加了这个功能。我认为最好传递对按钮的引用,然后您可以使用编辑器的内容。现在你想做什么更清楚了。 当然,没问题。您可以使用useEditor 钩子或上下文来完成。对于useEditor,请查看here,并在此处查看context example。两者都可以,但我更喜欢上下文方法——它更像 React 并且更容易阅读 IMO。诀窍是有一个editorRef(在组件树中较高),可以使用上下文方法从Editor 组件中设置。

以上是关于React 2020 中的 document.getElementById() 等效项的主要内容,如果未能解决你的问题,请参考以下文章

React 2020 中的 document.getElementById() 等效项

Js/Jquery获取iframe中的元素 在Iframe中获取父窗体的元素方法

JS document对象

完成注册功能

拖放期间未触发Javascript Drop事件

因异常 TypeError 暂停:document.getElementById(...) is null