Как вызвать функцию в React, когда два компонента не смонтированы? - PullRequest
1 голос
/ 16 июня 2020

Вызов функции (redux), когда один компонент React собирается размонтировать, может быть выполнен путем вызова функции внутри componentWillUnmount. Но мне интересно, как вызвать функцию (redux), когда два компонента React (которые находятся за отдельными URL-адресами) не смонтированы. Вот пример:

class App extends React.Component {
  render() {
    return (
      <Router history={history}>
        <Switch>
          <Route component={Foo} ... />
          <Route component={Bar} ... />
          // Many other routes
        </Switch>
      </Router>
    );
  }
}

class Foo extends React.Component<Props, State> {
    componentWillUnmount() {
        if (!navigated_to_bar()) {
            alert("Clear state");
        }
    }
}

class Bar extends React.Component<Props, State> {
    componentWillUnmount() {
        if (!navigated_to_foo()) {
            alert("Clear state");
        }
    }
}

Я хочу вызывать alert только в том случае, если пользователь ушел от обоих компонентов Foo и Bar; они могут перемещаться между этими компонентами столько раз, сколько захотят, не вызывая вызова alert.

Я довольно гибок с точки зрения решения, которое ищу: я ожидаю, что мне понадобится смена архитектурной парадигмы. Я думал, что решение может заключаться в том, чтобы у Foo / Bar был общий родительский компонент и каким-то образом настроить маршрутизатор.

1 Ответ

1 голос
/ 16 июня 2020

Самым простым решением было бы использовать иерархию родитель-> потомок и обновлять оттуда. Это типичное соглашение о реакции; Передайте функцию, позволяющую обновлять состояние родителей.

class App extends React.Component {
  componentDidMount() {
    this.state = {
      routedToFoo: null,
      routedToBar: null
    }
  }

  componentDidUpdate(_, prevState) {
     if (prevState.routedToFoo !== this.state.routedToFoo &&
            prevState.routedToBar !== this.state.routedToBar) {
          if (this.state.routedToFoo === false && this.state.routedToBar === false) 
              alert("Clear state");
      }
  }

  /* -- snip -- */
     <Route component={<Foo setRouted={routedToFoo => this.setState({ routedToFoo })} ... />
     <Route component={<Bar setRouted={routedToBar => this.setState({ routedToBar })}/>} ... />
  /* -- snip -- */
}

Затем внутри Bar и Foo:

componentDidMount() {
   this.props.setRouted(true);
}

componentWillUnmount() {
    this.props.setRouted(false);
}

Здесь я обрабатываю побочный эффект в componentDidUpdate. Мы слушаем, являются ли оба значения ложными и что хотя бы одно из значений было обновлено по сравнению с предыдущим состоянием, затем мы вызываем предупреждение «Очистить состояние».

Однако, если это недостаточно гибко, вы может захотеть рассмотреть возможность использования redux. https://redux.js.org/introduction/getting-started

Или Context: https://reactjs.org/docs/context.html

...