在React组件生命周期方法中,“ this.context”是一个空对象

时间:2018-10-24 11:13:42

标签: reactjs

在此React组件生命周期方法中,this.context为什么是空对象?

该上下文在Consumer中具有该上下文的正确值。只有this.context API失败。

const LoremContext = React.createContext({
    lorem: "ipsum",
})


class MenuItem extends React.Component {

    componentDidMount() {
        console.log(
            "In MenuItem.componentDidMount, this.context is:",
            this.context)
    }

    render() {
        console.log(
            "In MenuItem.render, this.context is:",
            this.context)
        return ( <LoremContext.Consumer>{
            (lorem) => {
                console.log("In LoremContext.Consumer, lorem is:", lorem)
                return (
                    <li>
                        { `Eat ${this.props.dish} at ${lorem}` }
                    </li>
                )
            }
        }</LoremContext.Consumer> )
    }
}

MenuItem.contextType = LoremContext

class Menu extends React.Component {
    render() {
        …
    }
}

class Application extends React.Component {
    render() {
        return (
            <LoremContext.Provider value={ this.props.world.lorem }>
                <section className="app">
                    <Menu menuItems={ [ … ] } />
                <p>Fusce varius id arcu egestas sodales</p>
            </section>
        </LoremContext.Provider>
    )
}

ReactDOM.render(
    <Application world={ { lorem: "consecteur" } } />,
    document.getElementById('app-container'),
)

这是使用React 16.4,因此它使用了documented context API(在React 16.3中引入)。

根据该文档化的API,以上代码应以两种方式访问​​上下文(在React.createContext的返回值中定义):

  • LoremContext.Consumer组件接收LoremContext.Provider传递的上下文值。

    然后,使用者将上下文值作为该组件内函数的参数提供。在这种情况下,lorem是接收上下文值的参数。

  • this.context属性在{生命周期方法“中接收(由于declared MenuItem.contextType class property)上下文值。

其中只有一个为我工作。

  • LoremContext.Consumer API正在正确获取和传递上下文值。 console.log的输出是:
  
  In LoremContext.Consumer, lorem is: consecteur
  • this.context没有获得正确的值,而是获得了一个空的Object。 console.log的输出是:
  
  In MenuItem.render, context is: Object {  }
  In MenuItem.componentDidMount, context is: Object {  }

因此,消费者正在接收正确的值,但this.context却没有。为什么会有所不同?如何获得在this.context收到的正确值?

3 个答案:

答案 0 :(得分:3)

this.context是在React 16.6中引入的,您可以看到here

在此版本之前,您正在使用16.4上的版本,可以在React Lifecycles中访问上下文:

class Button extends React.Component {
  componentDidMount() {
    // ThemeContext value is this.props.theme
  }

  componentDidUpdate(prevProps, prevState) {
    // Previous ThemeContext value is prevProps.theme
    // New ThemeContext value is this.props.theme
  }

  render() {
    const {theme, children} = this.props;
    return (
      <button className={theme || 'light'}>
        {children}
      </button>
    );
  }
}

export default props => (
  <ThemeContext.Consumer>
    {theme => <Button {...props} theme={theme} />}
  </ThemeContext.Consumer>
);

请参见docs for more information

答案 1 :(得分:1)

不幸的是,在目标组件中没有此部分,它是空的。

static contextType = ThemeContext; // assign the correct context 

像创建之前一样

const ThemeContext = React.createContext('light');

https://reactjs.org/docs/context.html

答案 2 :(得分:0)

尝试在单独的文件中创建上下文,然后将其导入。那对我有用。在使用createContext标签的同一文件中调用<MyContext.Provider>时,使用者仅看到一个空对象。当我将createContext移动到单独的文件时,使用者看到了期望值。这适用于两种消费方式-<MyContext.Consumer>MyClass.contextType/this.context

恐怕我无法解释为什么可行,但是我在this thread中找到了解决方案。