使用Context.Consumer而不是contextType反应上下文更新值

时间:2019-10-01 09:34:30

标签: reactjs react-context

我试图在React组件中使用React上下文,但是遇到了一些麻烦。

在我的Component.jsx中,我有一个这样的渲染方法:

render() {
    return (
      <NavigationProvider>
        <ShipmentsContext.Consumer>
          {({ isDetailsVisible }) => (
            <div>
              {this.renderHeader(isDetailsVisible)}
            </div>
          )}
        </ShipmentsContext.Consumer>
      </NavigationProvider>
    );
  }

这很好用,isDetailsVisible正在根据我的需要进行更新。

但是我想删除<ShipmentsContext.Consumer>并使用contextType,但是当我在isDetailsVisible方法中得到renderHeader时,它总是设置为false并且没有更新...

这是renderHeader

的代码
  • 使用<ShipmentsContext.Consumer>:(isDetailsVisible正在更新)
renderHeader(isDetailsVisible) {
    const { classes } = this.props;

    return (
      <Searchbar className={classNames({ [classes.nodeTranslated]: isDetailsVisible})}/>
    );
  }
  • 使用contextType:(isDetailsVisible 更新=>始终设置为默认值)
renderHeader() {
    const { classes } = this.props;
    const { isDetailsVisible } = this.context;

    return (
      <Searchbar className={classNames({ [classes.nodeTranslated]: isDetailsVisible })}/>
    );
  }

有什么主意吗?谢谢!

1 个答案:

答案 0 :(得分:0)

假设您的问题背景是ShipmentsContext,您是否偶然错过了相应的ShipmentsContext.Provider

您放下<ShipmentsContext.Consumer>并保留<ShipmentsContext.Provider>。可以在contextType的帮助下将上下文使用者设置为静态类字段:

class MyComp extends React.Component {
  static contextType = ShipmentsContext;
  ...
}

// When you don't want to/cannot use public class 
// fields syntax, this is the alternative:
// MyComp.contextType = ShipmentsContext;

这是一个简单的测试样本:

const ShipmentsContext = React.createContext({
  isDetailsVisible: "false from default"
});

class MyComp extends React.Component {
  static contextType = ShipmentsContext;

  render() {
    return this.renderHeader();
  }

  renderHeader() {
    return <p>{JSON.stringify(this.context)}</p>;
  }
}

const App = () => {
  // state realized with React Hooks. You could also use a 
  // class component and `setState` for App
  const [contextValue, setContextValue] = React.useState({
    isDetailsVisible: "true from Provider"
  });

  return (
    <ShipmentsContext.Provider value={contextValue}>
      <button
        onClick={() =>
          setContextValue({ isDetailsVisible: "UPDATED true from Provider" })
        }
      >
        Update Context
      </button>
      <MyComp />
    </ShipmentsContext.Provider>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.1/umd/react.production.min.js" integrity="sha256-vMEjoeSlzpWvres5mDlxmSKxx6jAmDNY4zCt712YCI0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.1/umd/react-dom.production.min.js" integrity="sha256-QQt6MpTdAD0DiPLhqhzVyPs1flIdstR4/R7x4GqCvZ4=" crossorigin="anonymous"></script>

<div id="root"></div>

通过单击“更新上下文”按钮,将为上下文提供一个新值,renderHeader也将收到有关更改的通知。

如果适合您的情况,请告诉我。祝你好运!