如何使用 mount() 更新嵌套组件的状态?

How can I update my nested component's state using mount()?

如果路径为 /search,我正在尝试测试我的组件是否呈现搜索组件。

这是我的测试:

it('renders Search when the correct URL is provided', () => {
  const wrapper = mount(
    <MemoryRouter initialEntries={['/search']} initialIndex={1}>
      <App />
    </MemoryRouter>
  ).find(App);
  expect(wrapper.find(Search)).toHaveLength(1);
});

App.js 渲染函数:

render() {
  const { loading } = this.state;
  let content;

  if (loading) {
    content = <Loading />;
  } else {
    content =
      <div>
        <Switch>
          <Route exact path="/" render={() => (<BookList data={this.state} onHandleChange={this.handleChange.bind(this)} onStarClick={this.starClick.bind(this)} />)} />
          <Route path="/search" render={() => (<Search data={this.state} onHandleChange={this.handleChange.bind(this)} onStarClick={this.starClick.bind(this)} />)} />
          <Route component={NotFound} />
        </Switch>
        <Footer />
      </div>;
  }
  return (
    <div className="App">
      {content}
    </div>
  );
}

我在寻找解决方案的过程中已经遇到的问题是:

  1. 使用 shallow:我可以更新 App 的状态。 Switch 抛出一个错误,指出它没有路由器,但它有,而且是 MemoryRouter。
  2. 使用挂载:我无法更新应用程序的状态。开关识别 MemoryRouter。

App的state.loading默认值为truecomponentDidMount()运行时更新为false

关于如何在使用 mount 时更新 App 的状态或使用 shallow 访问 Search 的方法有什么想法吗?

我设法通过重构我的代码并将 else 中的内容传递给它自己的组件来找到解决这个问题的方法:

const MainContent = (props) => {
  const { data, onHandleChange, onStarClick } = props;
  return(
    <Switch>
      <Route exact path="/" render={() => (<BookList data={data} onHandleChange={onHandleChange} onStarClick={onStarClick} />)} />
      <Route path="/search" render={() => (<Search data={data} onHandleChange={onHandleChange} onStarClick={onStarClick} />)} />
      <Route component={NotFound} />
    </Switch>
  )
};

然后我在MainContent.test.js中测试了我的路线:

it('renders <Search /> when path is `/search`', () => {
  const wrapper = mount(
    <MemoryRouter initialEntries={['/search']}>
      <MainContent data={body} onHandleChange={handleChange} onStarClick={starClick}/>
    </MemoryRouter>
  ).find(MainContent);
  expect(wrapper.find(Search)).toHaveLength(1);
});

希望这对遇到同样问题的人有所帮助。