【问题标题】:Find the matching React Node for a given HTML Node为给定的 HTML 节点查找匹配的 React 节点
【发布时间】:2021-11-03 12:16:16
【问题描述】:

以下示例:

const Home = () => <div id="demo">
  <h1>Hello World</h1>
</div>

是否有任何代码可以让我获得类似于 ReactDevTools Chrome 扩展的 JSX 元素及其道具?

const div = getElementById("demo");
// ??

【问题讨论】:

  • 对不起,如果我的问题很愚蠢。但是这种事情的用例是什么?我认为 useRef 不足以满足您的用例,对吗?
  • 不幸的是,我无法更改组件本身的源代码 - 我想编写一个小助手,允许使用alt + click直接跳转到任何组件的代码
  • 您可以尝试在official react packages 上查看react-devtools-* 源代码。
  • 使用它会破坏 react-dev-tools 因为只允许一个实例:github.com/facebook/react/blob/…

标签: reactjs


【解决方案1】:

如果您要求访问示例中的 h1 组件并为它设置一个值,我通常会这样做: const h1 = document.getElementById("demo").getElementByTagName('h1) 然后您可以使用innerHtml 设置值(或使用危险变量设置)。 h1 不需要是直接孩子。其他一些可以方便使用而不是getElementByTagName 来根据它们的类或 idis 或标签选择元素的函数...是:

querySelector()
querySelectors()
getElementsByClassname()

无论如何,不​​太确定这是否是您要求的!

【讨论】:

  • 否 - 我知道如何获取 html 元素 - 我正在寻找一种从中获取 JSX Element 实例的方法
【解决方案2】:

以下任何一个都将与 Alt+Click 一起使用以显示每个组件的道具。

使用HOC

您可以创建一个高阶组件来查看道具。您可以导出您希望此功能用withViewProps 包装的现有组件。

import React, { useState } from "react";

const withViewProps = (WrappedComponent) => {
  return (props) => {
    const [show, setShow] = useState(false);

    return (
      <div
        onClick={(e) => {
          setShow(e.altKey);
        }}
      >
        <>
          {show && (
            <>
              {WrappedComponent.name}
              {JSON.stringify(Object.entries(props))}
              <button onClick={() => setShow(false)}>x</button>
            </>
          )}
        </>
        <WrappedComponent {...props} />
      </div>
    );
  };
};

const Home = (props) => {
  return (
    <div>
      <h1>{props.text}</h1>
    </div>
  );
};

const WrappedHome = withViewProps(Home);

const App = () => {
  return (
    <>
      <WrappedHome
        text={"Hello World"}
        value={20}
        myF={() => {
          alert("Yes!");
        }}
      />
      <WrappedHome
        text={"Hello World"}
        value={20}
        myF={() => {
          alert("Yes!");
        }}
      />
    </>
  );
};

export default App;

Code Sandbox: HOC

使用Render Props

您可以创建根级组件来包装所有嵌套组件。然后您可以遍历所有嵌套的子项以添加查看道具的功能。这样您就不需要导出每个 React 组件。

import React, { useState, Children, isValidElement } from "react";

const ViewPropsAll = ({ children }) => {
  const renderChild = (children) => {
    return Children.map(children, (child) => {
      if (isValidElement(child)) {
        return (
          <ViewProps data={child.props}>
            <child.type
              {...child.props}
              children={renderChild(child.props.children)}
            />
          </ViewProps>
        );
      }
      return child;
    });
  };

  return <>{renderChild(children)}</>;
};

const ViewProps = (props) => {
  const [show, setShow] = useState(false);

  return (
    <div
      onClick={(e) => {
        setShow(e.altKey);
      }}
    >
      <>
        {show && (
          <>
            {JSON.stringify(Object.entries(props.data))}
            <button onClick={() => setShow(false)}>x</button>
          </>
        )}
      </>
      {props.children}
    </div>
  );
};

const Home = (props) => {
  return (
    <div>
      <h1>{props.text}</h1>
    </div>
  );
};

const App = () => {
  return (
    <ViewPropsAll>
      <Home
        text={"Hello World"}
        value={20}
        myF={() => {
          alert("Yes!");
        }}
      />
      <Home
        text={"Hello Hello"}
        value={30}
        myF={() => {
          alert("Noo!");
        }}
      />
    </ViewPropsAll>
  );
};

export default App;

Code Sandbox: Render Props

【讨论】:

  • @jantimon,看看这个!!
  • 嘿@amila - 感谢非常酷的 POC! :) 我正在寻找一种不需要更改应用程序代码本身并且也不需要注入额外 HTML 元素的方法 - 类似于 react-dev-tools
  • 好的,但是您可以更改逻辑以显示工具提示,而不是根据需要添加 HTML。这不是您添加到代码中的功能吗?或者它实际上是您开发的 rect-dev-tools 的替代 chrome 扩展?
【解决方案3】:

在 javascript 中,您可以使用 getElementById https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById

但是 React 有一个内置的钩子可以让你访问子引用。检查useRef 文档https://reactjs.org/docs/hooks-reference.html#useref

示例

import React, { useRef } from 'react';

const Home = () => {
  const ref = useRef(null);

  console.log(ref)
 
  return (
    <div ref={ref}>
      <h1>Hello World</h1>
    </div>
  )
}

useRef 只会在你将 ref 传递给 React 组件时返回状态和道具。在您的情况下,它将返回 HTML 元素

【讨论】:

    猜你喜欢
    • 2011-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多