侦听使用者组件中的ReactContext变量更改

时间:2019-05-07 02:27:54

标签: reactjs subscribe react-context

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

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

每当变量“ myName”更改时,我都想进行ajax调用,获取一些数据(例如age)并将其显示在组件中。我一直在寻找一种方法来监听“ myName”的更改,最好的方法是什么?我注意到,尽管该组件反映了最新的“ myName”,但是当myName更改时,不会调用任何React生命周期方法。

2 个答案:

答案 0 :(得分:0)

您需要向班级(docs)添加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的类似版本。

答案 1 :(得分:0)

如果您以某种方式构成组件,例如将当前上下文作为道具传递给执行提取的组件,那么您也可以使用React生命周期方法。

这是一个带有React hooks -implementation CodeSandbox -example的简短虚拟示例。

此示例的重点

class WeatherViewModelTests: XCTestCase {

var classUnderTest: WeatherViewModel!
let mockInteractor = MockWeatherInteractor()
let mockDelegate = MockBaseViewModelDelegate()

 override func setUp() {
    classUnderTest = WeatherViewModel(interactor: mockInteractor,
                                      delegate: mockDelegate)
 }

func testThatClosureReturnsCorrectValue() {
    var mockUpdates: [Weather]? = nil
    var testBool = false

    stub(mockInteractor) {
        when($0.fetchCityWeather( success: anyClosure(), failure: anyClosure())).then({ success, _ in
            testBool = true
            success(mockUpdates)
        })
    }

    classUnderTest.getUpdates()

    XCTAssertTrue(testBool)
  }

}