Does React have something like Vue's keep-alive element?

Viewed 5861

Vue keep-alive element will remember page state when back history page, hope React has something like that.

3 Answers

React does not have this type of feature, and a recent maintainer response on the same issue pretty strongly indicates they don't think this is a good idea. However, the same thread discusses a standard alternative, which is to implement your logic so that you are not deleting/creating the components but rather hiding and showing them. For instance, if you did something like this to support "tabs":

{this.state.activeTab === 1 &&
<MyFirstTabView/>
}
{this.state.activeTab === 2 &&
<MySecondTabView/>
}

then MyFirstTabView will obviously be destroyed when the second tab is selected. However, if you did it this way:

<MyFirstTabView className={this.state.activeTab === 1 ? 'active' : ''}/>
<MySecondTabView className={this.state.activeTab === 2 ? 'active' : ''}/>

and paired this with a CSS display: none or display: block rule, it would achieve a similar thing to Vue's keep-alive feature. It's not QUITE as efficient, but for common use-cases like tab switching, it's close.

React offers keep alive through a package. To install this package, To install Run:

npm install --save react-keep-alive

import React from 'react';
import ReactDOM from 'react-dom';
import {
  Provider,
  KeepAlive,
} from 'react-keep-alive';
import Test from './views/Test';
 
ReactDOM.render(
  <Provider>
    <KeepAlive name="Test">
      <Test />
    </KeepAlive>
  </Provider>,
  document.getElementById('root'),
);

You can look at the components I wrote.

react-keep-alive

It implements a similar function of vue keep-alive, For example, if we enter the B page from the A page, we don't need to cache it. But when the B page enters the C page and returns to the B page, the B page needs to be cached. This is a very common requirement.

There are two basic components in react-keep-alive, <Provider> and <KeepAlive>. You need to wrap your application with <Provider> and then use <KeepAlive> to wrap the components you want to cache. You will find that the component has been cached.

import React from 'react';
import ReactDOM from 'react-dom';
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
} from 'react-router-dom';
import {
  Provider,
  KeepAlive,
} from 'react-keep-alive';

class A extends React.Component {
  render() {
    return (
      <div>This is A.</div>
    );
  }
}

class B extends React.Component {
  render() {
    return (
      <div>This is B.</div>
    );
  }
}

class C extends React.Component {
  render() {
    return (
      <div>This is C.</div>
    );
  }
}

class App extends React.Component {
  state = {
    disabled: false,
  };

  handleNotCache = () => {
    this.setState({
      disabled: true,
    });
  }

  handleNeedCache = () => {
    this.setState({
      disabled: false,
    });
  }

  handleActivate = () => {
    console.log('B activated');
  }

  handleUnactivate = () => {
    console.log('B unactivated');
  }

  render() {
    const {disabled} = this.state;
    return (
      <div>
        <ul>
          <li onClick={this.handleNotCache}>
            <Link to="/a">a</Link>
          </li>
          <li>
            <Link to="/b">b</Link>
          </li>
          <li onClick={this.handleNeedCache}>
            <Link to="/c">c</Link>
          </li>
        </ul>
        <Switch>
          <Route path="/a">
            <A />
          </Route>
          <Route path="/b">
            <KeepAlive
              key="B"
              disabled={disabled}
              onActivate={this.handleActivate}
              onUnactivate={this.handleUnactivate}
            >
              <B />
            </KeepAlive>
          </Route>
          <Route path="/c">
            <C />
          </Route>
        </Switch>
      </div>
    );
  }
}

ReactDOM.render(
  <Router>
    <Provider>
      <App />
    </Provider>
  </Router>,
  document.getElementById('root'),
);

More specific usage and API documentation can be viewed in the link above.

Related