如果反应路由器参数保持不变,则防止重新安装布局组件

时间:2019-02-18 10:55:30

标签: reactjs optimization react-router

我有一个布局组件,可以渲染很大尺寸的图像。此布局组件在其他两个组件(地图和浏览)之间共享。更改路线时,它将渲染“地图”或“探索”组件,并在其周围包裹布局组件。

用户可以通过主页进入“地图”或“探索”。因此,指向页面的链接可以是“ ... / map / 123”或“ ... / explore / 456”。当用户进入地图或浏览组件时,在地图和浏览之间切换时,URL参数始终保持不变。所以'... / map / 123'或'... / explore / 123'

每次路线更改时,都会重新渲染布局组件和地图/探索组件。问题在于,然后重新获取布局组件上的大图像。

我应该如何构造应用程序,以便无需重新获取大图像就可以从地图和浏览中切换?

我在this sandbox中有代码...

//index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route, NavLink } from "react-router-dom";

import "./styles.css";

import Map from "./Map";
import Explore from "./Explore";

const Links = props => {
  return (
    <nav>
      <NavLink exact to="/">
        Home
      </NavLink>
      <NavLink style={{ paddingLeft: "5px" }} to="/map/1">
        Map
      </NavLink>
      <NavLink style={{ paddingLeft: "5px" }} to="/explore/1">
        Explore
      </NavLink>
    </nav>
  );
};

function App() {
  return (
    <Router>
      <div>
        <Links />
        <Route exact path="/" render={() => <h1>Home</h1>} />
        <Route path="/map/:id" render={({ match }) => <Map match={match} />} />
        <Route
          path="/explore/:id"
          render={({ match }) => <Explore match={match} />}
        />
      </div>
    </Router>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

//layout MapExploreContainer.js
import React, { Component } from "react";

class MapExploreContainer extends Component {
  state = { imgUrl: null };

  componentDidMount() {
    this.timeout = setTimeout(() => {
      this.setState({
        imgUrl:
          "https://images.unsplash.com/photo-1550396011-0d98206d5b92?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjU1Nzk4fQ"
      });
    }, 2000);
  }

  componentWillUnmount() {
    clearInterval(this.timeout);
  }

  render() {
    console.log("hi: ", this.props.match);
    return (
      <div style={{ border: "1px solid black" }}>
        <img src={this.state.imgUrl} />
        {this.props.children}
      </div>
    );
  }
}

export default MapExploreContainer;

//Map.js
import React, { Component } from "react";
import MapExploreContainter from "./MapExploreContainer";

class Map extends Component {
  render() {
    return (
      <MapExploreContainter match={this.props.match}>
        <div>Map</div>
      </MapExploreContainter>
    );
  }
}

export default Map;

//Explore.js
import React, { Component } from "react";
import MapExploreContainter from "./MapExploreContainer";

class Explore extends Component {
  render() {
    return (
      <MapExploreContainter match={this.props.match}>
        <div>Explore</div>
      </MapExploreContainter>
    );
  }
}

export default Explore;

1 个答案:

答案 0 :(得分:0)

我认为这里的问题是ExploreMap各自拥有自己的MapExploreContainer实例,而在卸载这些组件中的每个组件时,它们也会被卸载。

您可以尝试以下操作:

MapExploreContainterMap删除对Explore的所有引用

将路线更改为:

function App() {
  return (
    <Router>
      <div>
        <Links />
        <Route exact path="/" render={() => <h1>Home</h1>} />
        <Route path="/(map|explore)/:id" component={MapExploreContainter} />
        <Route path="/map/:id" render={({ match }) => <Map match={match} />} />
        <Route
          path="/explore/:id"
          render={({ match }) => <Explore match={match} />}
        />
      </div>
    </Router>
  );
}

这样,无论您何时MapExploreContainermap/123,呈现的explore/123总是相同的实例。

更新的沙箱:https://codesandbox.io/s/14xj47667j