Reaction将“This”传递给上下文提供程序值

c9qzyr3d  于 2022-09-18  发布在  Java
关注(0)|答案(1)|浏览(162)

我在使用类组件中的useContext。我已经创建了一个简单的Reaction(Nextjs)应用程序,只需一个按钮,就可以在上下文中调用更新状态的函数,从而重新呈现主组件。

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

export default function Home() {
    let [contex] = useContext(UserContext);
    // Without the destructuring assignment
    // 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 ( // Changing value to value={this}
            <UserContext.Provider value={[this]}>
                {this.props.children}
            </UserContext.Provider>
        );
    }
}

注意:它 Package 到_app.js内的整个应用程序的提供程序

这可以很好地工作,但是我想知道为什么我被迫在数组中传递this

value={[this]}

当我尝试只传递这个(value={this})并修改上下文时

let contex = useContext(UserContext)

Home函数不再对状态的更改做出React,因此不会重现。

根据我的编程知识,这两个选项的行为应该完全相同。

这是怎么回事?

ilmyapht

ilmyapht1#

问题

您只是“被迫”将上下文值作为value={[this]}传递,因为这是您在使用者中访问它的方式。

let [contex] = useContext(UserContext);

这里使用数组析构赋值数组中获取可访问的上下文值

contex.state.count

换句话说,this.state.countcontex.state.count是一回事。

更重要的是,您被迫从数组中使用它,因为它就是这样提供的:value={[this]}

解决方案

与其传递根父类组件的整个this对象,不如只传递您需要的*,比如只传递count状态和addOne回调函数。

示例:

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>
      ))}
    </>
  );
}

不过,这里的主要要点应该是,无论您如何消费,上下文值应该与您提供它的方式相匹配。

相关问题