简体   繁体   English

React 将“this”传递给上下文提供者值

[英]React pass "this" to context provider value

I was playing around with useContext in a class component.我在 class 组件中使用 useContext 。 I've created a simple react (nextjs) application with one button that call a function in the context that update the state and therefore re-render the home component.我用一个按钮创建了一个简单的 react (nextjs) 应用程序,在更新 state 的上下文中调用 function 并因此重新渲染 home 组件。

import { useContext } from "react";
import { UserContext } from "../provider/TestProvider";

export default function Home() {
    let [contex] = useContext(UserContext);

    return (
        <>
            <button onClick={() => contex.addOne()}>Add 1</button>
            {contex.state.count.map((e) => (
                <div key={Math.random()}> {e} </div>
            ))}
        </>
    );
}
import { createContext, Component } from "react";

export const UserContext = createContext();

export default class TestProvider extends Component {
    state = {count: []};

    constructor(props) {
        super(props);
        this.props = props;
    }

    addOne() {
        let oldState = [...this.state.count];
        oldState.push("test");
        this.setState({ count: oldState });
    }

    render() {
        return (
            <UserContext.Provider value={[this]}>
                {this.props.children}
            </UserContext.Provider>
        );
    }
}

Note: The provider it's wrapped to the entire application, inside _app.js注意:它被包装到整个应用程序的提供程序,在_app.js

this is working fine, however I was wondering why I'm forced to pass this inside an array ( value={[this]} )?这工作正常,但是我想知道为什么我不得不在数组( value={[this]} this中传递它? When I tried to pass only this ( value={this} ) [and modify the context let contex = useContext(UserContext) ], the Home function doesn't react anymore on the change of the state, and therefore no rerender.当我试图只传递这个( value={this} )[并修改上下文let contex = useContext(UserContext) ] 时,Home function 不再对 state 的更改做出反应,因此不会重新渲染。

From my knowledge of programming both options should behave exactly the same.根据我对编程的了解,这两个选项的行为应该完全相同。

What is happening here?这里发生了什么?

Issue问题

You are only "forced" to pass the context value as value={[this]} because that is how you are accessing it in the consumer.您只是“被迫”将上下文值作为value={[this]}传递,因为这就是您在消费者中访问它的方式。

let [contex] = useContext(UserContext);

Here you are using array destructuring assignment to get the context value out of the array and accessible.在这里,您使用数组解构赋值数组中获取上下文值并且可以访问。

contex.state.count

In other words, this.state.count and contex.state.count are the same thing.也就是说, this.state.countcontex.state.count是一回事。

It rather more that you are forced to consume it from an array because that is how it was provided: value={[this]} .更多的是您被迫从数组中使用它,因为它是这样提供的: value={[this]}

Solution解决方案

Instead of passing the entire this object of the root parent class component it would be better to pass only what you need to, like only the count state and the addOne callback function. Instead of passing the entire this object of the root parent class component it would be better to pass only what you need to, like only the count state and the addOne callback function.

Example:例子:

export const UserContext = createContext({
  addOne: () => {},
  count: [],
});

export default class TestProvider extends Component {
  state = { count: [] };

  addOne = () => {
    this.setState(prevState => ({
      count: [...prevState.count, "test"];
    }));
  }

  render() {
    const { children } = this.props;
    const { count } = this.state;
    return (
      <UserContext.Provider value={{ addOne, count }}> // provided as object
        {children}
      </UserContext.Provider>
    );
  }
}

... ...

import { useContext } from "react";
import { UserContext } from "../provider/TestProvider";

export default function Home() {
  const { addOne, count } = useContext(UserContext); // object destructuring assignment

  return (
    <>
      <button onClick={addOne}>Add 1</button>
      {count.map((e) => (
        <div key={e}>{e}</div>
      ))}
    </>
  );
}

The main takeaway here though should be that however you are consuming the context value should match how you are providing it.不过,这里的主要内容应该是,您使用的上下文值应该与您提供它的方式相匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM