【问题标题】:Is Context.Provider and Context.Consumer the same as document.querySelector() in JavaScript?Context.Provider 和 Context.Consumer 和 JavaScript 中的 document.querySelector() 一样吗?
【发布时间】:2020-04-15 21:31:51
【问题描述】:

我只想在单击按钮时在 Home.js 中获取 div 的文本...我已经设置了 createContext();

我尝试使用 Refs 它不起作用..所以现在我正在尝试 createContext()... Home.js 中一个 div 的文本内容。

live code

Index.js:

import React from "react";
import ReactDOM from "react-dom";
import { ThemeContextProvider } from "./themeContext";

import App from "./App";
const RootElement = document.getElementById("root");

ReactDOM.render(
  <ThemeContextProvider>
    <App />
  </ThemeContextProvider>,
  RootElement
);

themeContext.js:

import React, { Component } from "react";
const { Provider, Consumer } = React.createContext();

class ThemeContextProvider extends Component {
  state = {
    test: "test"
  };

  handleChange = () => {
    this.test.textContent
  };

  render() {
    return (
      <Provider
        value={{ test: this.state.test, handleChange: this.handleChange }}
      >
        {this.props.children}
      </Provider>
    );
  }
}

export { ThemeContextProvider, Consumer as ThemeContextConsumer };

Button.js:

import React from "react";
import { ThemeContextConsumer } from "./themeContext";

export default function Button(props) {
  return (
    <>
      <ThemeContextConsumer>
        {context => <button onClick={context.handleChange}>ooMe</button>}
      </ThemeContextConsumer>
    </>
  );
}

Home.js:

import React from "react";
import { ThemeContextConsumer } from "./themeContext";
import Button from "./Button";

export default function Home(props) {
  return (
    <>
      <ThemeContextConsumer>
        {context => (
          <>
            <div className={context.test}>You Exposed Me!</div>
            <br />
            <h4>
              Button From Test:
              <br />
              <Button handleChange={context.handleChange} />
            </h4>
          </>
        )}
      </ThemeContextConsumer>
    </>
  );
}

App.js

import React from "react";
import "./styles.css";
import Home from "./Home";
import Another from "./Another";

export default function App() {
  return (
    <div className="App">
      <Home />
      <Another />
    </div>
  );
}

【问题讨论】:

  • React Context 是关于将数据向下传递给子组件,而不必通过每个中间树节点传递它们。它甚至无法与querySelector() 相比。
  • 是的,我注意到 React 比传统的 JavaScript 更难使用。而且很难找到像样的文档
  • 那么您的目标是什么?有一个孩子导致另一个孩子发生变化吗?因为“获取 div 的文本”听起来很奇怪。
  • 基本上当我的按钮被点击时,我希望从 Home.js
    You Exposed Me!
    中的 div 中获取文本内容。单击按钮时,它应该返回 You Exposed Me!类似于 document.getElementById(".test").textContent 将如何返回 You Exposed Me!我一直在尝试找出在 React.js 中执行此操作的正确方法
  • 主要问题是你需要先正确使用createRef()ref。然后你需要让它们成为上下文的一部分:codesandbox.io/s/exciting-darwin-x602c?file=/src/…

标签: javascript reactjs dom


【解决方案1】:

如果您的意图只是获取元素值,那么您可以使用 refs。

function App() {
  const divRef = React.useRef(null);

  function handleClick() {
    console.log(divRef.current.textContent);
  }

  return (
    <div>
      <div ref={divRef} onClick={handleClick}>
        Foo
      </div>
      <Button onClick={handleClick} />
    </div>
  );
}

function Button({ onClick }) {
  return <button onClick={onClick}>Click me</button>
}

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

当您第一次检查您正在尝试的库的基本步骤时,这很简单。有大量体面的文档。

另外,如果你打算使用 React,我强烈建议你以 React 的方式思考。您不会看到很多代码试图获取这样的元素值。

【讨论】:

  • 所以不需要createContext?当我单击来自按钮组件的按钮时,我可以按照您的示例访问带有 className={test} 的 div 组件吗?
  • 我问是因为我在之前的尝试中尝试过使用 useRef 并收到 ReferenceError test is undefined
  • React Context 完全是另一个概念,正如@Chris G 对您的问题的评论。同样,如果您的意图是“仅获取 div 的内容”,就像我在示例中所做的那样,那么除了 refs 之外您不需要任何东西。我不知道您是如何尝试的,但正如您所看到的,您应该创建一个 ref,然后将其设置为您的元素,就像我在示例中所做的那样。
  • 谢谢,但根据我的示例,这不是我想要的。您所拥有的是 App 组件,它使用 ref 呈现 div 并导入组件按钮。它确实有效,但不是我想要的。不管怎样,谢谢。
【解决方案2】:

我使用上面的@devserken 示例和这个solution 来提出这个solution。我使用来自this example 的组件名称,因为组件名称不是我想要学习的重点。我的目标是学习如何抓取/捕获 DOM 元素,在这种特殊情况下,当单击按钮时,控制台会记录 textContent。

【讨论】:

    【解决方案3】:

    嘿,我更新了链接 https://codesandbox.io/s/winter-cdn-uqc5c

    如果你想更新你需要调用的视图,基本上是在反应

    setState
    

    触发重新渲染

    更多信息:https://reactjs.org/docs/react-component.html#setstate

    【讨论】:

    • 为什么投反对票? op 处理状态的方式存在一些基本问题
    • 谢谢。但我希望从此 div 中获取文本内容,该 div 位于 Home.js
      You Exposed Me!
      中。单击按钮时,它应该返回 You Exposed Me!
    • 我投了反对票,因为这个问题是关于其他事情的
    • 你暴露了我 .. 应该处于反应状态并且那个类名没有意义 tbh
    猜你喜欢
    • 2020-07-19
    • 2019-11-10
    • 1970-01-01
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-27
    相关资源
    最近更新 更多