Могу ли я использовать ref.current.setState (...) - PullRequest
0 голосов
/ 23 марта 2019

У меня есть ситуация, когда я хочу назвать Child.method из Parent, хотя это не лучшая практика, но я просто хочу попробовать.И я решил использовать ref.current.setState() в компоненте Parent.

Вот пример кода.https://codesandbox.io/s/8lmvq3yq68

Произошло неожиданное поведение, когда ref, setState и react-router-dom используются вместе.Когда я использую Redirect и ref вместе, Child.componentDidUpdate не будет вызван.Интересно, это правильный код в React?Так как я не могу найти какой-либо документ, который показывает его недействительным.Или это ошибка react-router-dom?

1 Ответ

0 голосов
/ 23 марта 2019

Я уточнил некоторые дополнительные журналы жизненного цикла компонентов. Так что происходит, когда вы выбираете «Ссылка» на «/». Будет запущено 2 параллельных вызова.

  1. Перейти к маршруту '/'
  2. Событие onClick

Таким образом, один сначала перейдет к соответствующему маршруту, а другой вызовет функцию ссылки. Вы увидите журнал «Вызов изменения состояния».

Что произойдет, когда вы перейдете к пути '/', это то, что SuperHero компонент размонтирован! и вы увидите «Размонтирование - супергерой» журнал. Таким образом, изменение состояния будет потеряно, и componentDidUpdate не будет запущен. Тем не менее, как вы можете видеть, перенаправление происходит и компонент снова монтируется. Теперь это не имеет смысла государства изменить, но "Mounting - Superhero" будет зарегистрирован.

Я также включил отдельную кнопку. Поскольку нет размонтирования, это работает как вы ожидаете!

https://codesandbox.io/s/81v0mz0548

import React from "react";
import ReactDOM from "react-dom";
import {
  BrowserRouter as Router,
  Link,
  Redirect,
  Route
} from "react-router-dom";

import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.superheroElement = React.createRef();
  }
  handleClick = () => {
    this.superheroElement.current.changeName();
  };
  render() {
    return (
      <Router>
        <Link to={"/"} onClick={this.handleClick}>
          haha
        </Link>
        <Route path="/" exact={true} render={() => <Redirect to="/post" />} />
        <Route
          path="/post"
          render={props => <Superhero ref={this.superheroElement} {...props} />}
        />
        <br/>
        <button  onClick={this.handleClick}>
          haha
        </button>
      </Router>
    );
  }
}

class Superhero extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: "Batman"
    };
    this.changeName = this.changeName.bind(this);
  }

  changeName() {
    console.log("Calling the state change");
    this.setState({
      name: "Bruce Wayne"
    });
  }

  componentDidUpdate() {
    // Not called because component is unmounted
    console.log("Updating - Superhero");
  }

  componentDidMount() {
    console.log("Mounting - Superhero");
  }

  componentWillUnmount() {
    console.log("Unmounting - Superhero");
  }

  render() {
    return <div>{this.state.name}</div>;
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...