Запретите повторный монтаж компонента компоновки, если параметры реагирующего маршрутизатора остаются прежними - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть компонент макета, который отображает изображение довольно большого размера.Этот компонент макета используется совместно двумя другими компонентами, Map и Explore.Когда маршрут изменяется, он отображает либо компонент Map, либо Explore, а компонент макета оборачивается вокруг него.

Пользователь попадает в Map или Explore через домашнюю страницу.Таким образом, ссылка на страницу может быть «... / map / 123» или «... / explore / 456».При переключении между картой и исследованием, когда пользователь находится на карте или в компоненте исследования, параметры URL остаются неизменными всегда.Поэтому '... / map / 123' или '... / explore / 123'

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

Как мне структурировать приложение, чтобы я мог выбирать из Map and Explore без необходимости повторного получения большого изображения?

У меня есть код в этой песочнице ...

//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 голосов
/ 18 февраля 2019

Я думаю, что проблема в том, что Explore и Map каждый получает свой собственный экземпляр MapExploreContainer, который демонтируется, когда каждый из этих компонентов демонтируется.

Вы можете попробовать что-то вроде следующего:

Удалить все ссылки на MapExploreContainter из Map и 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>
  );
}

Таким образом, визуализированный MapExploreContainer всегда является одним и тем же экземпляром, когда вы находитесь на map/123 или explore/123.

Обновленная песочница: https://codesandbox.io/s/14xj47667j

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...