Q:

Can I use ref.current.setState(...)

I have a situation that want to call a Child.method from Parent, though this is not a best practice, but I just want to give it a try. And I decide to use ref.current.setState() in the Parent component. 
Here is the example code.
https://codesandbox.io/s/8lmvq3yq68
There are some unexpected behavior happened where ref, setState and react-router-dom are used together. When I use Redirect and ref together, the Child.componentDidUpdate will not be called. I wonder if it is a valid code in React? Since I can not find any doc that showing it is invalid. Or is it a bug of react-router-dom?

A:

I logged in some additional component lifecycle logs to clarify.
So what's happening is when you select the 'Link' to '/' There are 2 parallel calls that will fire.

Navigate to the '/' route
The onClick event

So one will first navigate to the relevant route while the other will trigger the ref's function. You will see the "Calling the state change" log. 

What happens when you route to the '/' path is that the SuperHero
  component is unmounted! And you will see the "Unmounting - Superhero"
  log. So the state change is lost and componentDidUpdate will not be fired. Nevertheless, as you can see, the redirect does happen
  and the component is mounted again. Now it has no sense of the state
  change but the "Mounting - Superhero" will be logged.

I have further included a separate button. Since there is no unmounting, this works as you expect!
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);

