聆听ReactContext变量消费者组件的变化



我正在使用项目中的reactContext,在这里我使用某些上下文变量有一个'消费者'组件。一切正常,除非我尝试"听"更改变量'myName'。

<MyContext.Consumer>
      {context => {
        return (
          <div>Hello, {context.myName}, your title is age {...}</div>
        )
      }}
</MyContext.Consumer>

每当要变量" myName"更改时,我想进行ajax调用,获取一些数据(例如年龄(并将其显示在组件中。我正在寻找一种听取" myname"更改的方式,这是最好的方法?我注意到,尽管该组件反映了最新更新的" myName",但是当myName更改时,任何React Lifecycle方法都没有调用。

您需要在类(文档(中添加contextType属性。然后,您可以在生命周期方法中访问更新的上下文。我将一个示例从文档更改为显示。请参阅ThemedButton组件。您可以评论static contextType,并注意组件未接收上下文。

const ThemeContext = React.createContext("light");
class App extends React.Component {
  state = {
    theme: "dark"
  };
  render() {
    // Use a Provider to pass the current theme to the tree below.
    // Any component can read it, no matter how deep it is.
    // In this example, we're passing "dark" as the current value.
    return (
      <ThemeContext.Provider value={this.state.theme}>
        <button
          onClick={() => {
            this.state.theme === "dark"
              ? this.setState({ theme: "light" })
              : this.setState({ theme: "dark" });
          }}
        >
          Change theme
        </button>
        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}
// A component in the middle doesn't have to
// pass the theme down explicitly anymore.
function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}
class ThemedButton extends React.Component {
  // Assign a contextType to read the current theme context.
  // React will find the closest theme Provider above and use its value.
  // In this example, the current theme is "dark".
  static contextType = ThemeContext;
  componentDidUpdate() {
    console.log("Update", this.context);
  }
  render() {
    return <div>{JSON.stringify(this.context)}</div>;
  }
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

如果您没有可用的公共类字段语法,则可以使用ThemedButton.contextType = ThemeContext的类似版本。

如果您只是以一种示例将当前上下文作为道具的方式组成的组件,将当前上下文作为支架传递给组件,您可以使用React React LifeCycle方法。

这是一个简短的虚拟示例,带有react钩子 - 实体代码box -example。

此示例的要点,

// Initialize context
const context = React.createContext({ name: "" });
/**
 * My provider component which has it's own state
 * for updating existing context.
 */
const MyProvider = ({ children }) => {
  const [state, setState] = React.useState({ name: "" });
  return (
    <context.Provider value={state}>
      <input
        value={state.name}
        onChange={({ target }) => {
          console.log(target.value);
          setState({ name: target.value });
        }}
      />
      {children}
    </context.Provider>
  );
};

/**
 * Context to consume existing parent component context
 */
const MyConsumer = ({ children }) => {
  return <context.Consumer>{ctx => <MyComponent {...ctx} />}</context.Consumer>;
};
/**
 * provide values as props to your component with lifecycle-methods.
 */
const MyComponent = ({ name }) => {
  const [fetchResult, setResult] = React.useState({});
  React.useEffect(() => {
    console.log("child updated with name: ", name);
    /**
     * Fetch some data and set it to local state
     */
    const mockFetchResult = {
      title: name + `n${Math.random() * 1024}` // Dummy example to get some random data
    };
    setResult(mockFetchResult);
  }, [name]);
  return <p>{fetchResult.title}</p>;
};

最新更新