使用 componentdidupdate 响应上下文

god*_*oda 4 lifecycle reactjs

我正在运行这样的模式,假设SearchResultsContainer已安装并且某个搜索栏设置了输入。

class SearchResults {
   render() {
      return(
        <ResultsContext.Consumer value={input}>
        {input => <SearchResultsContainer input=input}
        </ResultsContext.Consumer>
   )
}

class SearchResultsContainer
  componentDidUpdate() {
      //fetch data based on new input
      if (check if data is the same) {
        this.setState({
          data: fetchedData
        })
      }
  }
}
Run Code Online (Sandbox Code Playgroud)

每当调用新的上下文值时,这将调用双重提取,因为 componentDidUpdate() 将触发并设置数据。在来自结果上下文的新输入上,它将调用componentDidUpdate()、获取、设置数据,然后调用componentDidUpdate()和获取,然后将检查数据是否相同并停止循环。

这是使用上下文的正确方法吗?

Ste*_*e L 8

我使用的解决方案是通过高阶组件将上下文传输到道具。

我已经使用了这个非常有用的 github 答案https://github.com/facebook/react/issues/12397#issuecomment-374004053

结果看起来像这样 my-context.js::

import React from "react";

export const MyContext = React.createContext({ foo: 'bar' });

export const withMyContext = Element => {
  return React.forwardRef((props, ref) => {
    return (
      <MyContext.Consumer>
        {context => <Element myContext={context} {...props} ref={ref} />}
      </MyContext.Consumer>
    );
  });
};
Run Code Online (Sandbox Code Playgroud)

使用上下文的另一个组件:

import { withMyContext } from "./path/to/my-context";

class MyComponent extends Component {
 componentDidUpdate(prevProps) {
    const {myContext} = this.props
    if(myContext.foo !== prevProps.myContext.foo){
      this.doSomething()
    }
  }
}
export default withMyContext(MyComponent);
Run Code Online (Sandbox Code Playgroud)

某处必须有上下文生产者:

<MyContext.Provider value={{ foo: this.state.foo }}>
  <MyComponent />
</MyContext.Provider>

Run Code Online (Sandbox Code Playgroud)