Как генерировать динамические маршруты в реагирующем маршрутизаторе? - PullRequest
0 голосов
/ 11 июля 2019

Я пытаюсь создать список домов, и каждый дом при нажатии будет указывать на отдельную страницу с данными об этом доме.В настоящее время все данные являются статическими данными, которые я создал в своем конструкторе с именем leaseData.Я хочу, чтобы Route path указывал на /dashboard/lease-id.Я пытаюсь передать и адрес, и monthRent в компонент Lease, чтобы я мог отобразить эти данные в новом компоненте.Как мне это сделать?

import React, { Component } from 'react'
import { Link, Route } from 'react-router-dom'
import { Lease } from './Lease'

class Dashboard extends Component {
  constructor(props) {
    super(props)
    this.match = this.props.match

    this.leaseData = [
      {
        id: 1,
        address: '18291 Rainbow Dr, Cool Springs CA 93102',
        monthlyRent: 4300
      },
      {
        id: 2,
        address: '2200 Stiller Dr, Las Vegas NV 96274',
        monthlyRent: 1500
      },
      {
        id: 3,
        address: '21626 Sleepy Hollow Ct, Walnut CA 91763',
        monthlyRent: 2400
      }
    ]
  }

  render() {

    let linkList = this.leaseData.map(lease => {
      return (
        <li>
          <Link to={`${this.match.url}/${lease.id}`}>
          <img src="https://cdn.edinarealty.com/media/2256/homepage-tiles_new-construction.jpg" alt="HTML5 Icon"></img>
          </Link>
        </li>
      )
    })

    return (
      <div>
        MAIN DASHBOARD
        <ul>
         <li> {linkList} </li>
        </ul>
        <Route path={`${this.match.url}/:lease-id`} render={<Lease data={}/>}/>
      </div>
    )
  }
}

Ответы [ 3 ]

1 голос
/ 11 июля 2019

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

Вот песочница для справки: https://codesandbox.io/s/suspicious-merkle-4bxv3

App.js

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route } from "react-router-dom";
import Dashboard from "./Dashboard";
import Lease from "./Lease";

import "./styles.css";

class App extends React.Component {
  state = {
    leaseData: [
      {
        id: 1,
        address: "18291 Rainbow Dr, Cool Springs CA 93102",
        monthlyRent: 4300
      },
      {
        id: 2,
        address: "2200 Stiller Dr, Las Vegas NV 96274",
        monthlyRent: 1500
      },
      {
        id: 3,
        address: "21626 Sleepy Hollow Ct, Walnut CA 91763",
        monthlyRent: 2400
      }
    ],
    selected: null
  };

  changeSelected = id => {
    this.setState({
      selected: this.state.leaseData.find(lease => lease.id == id)
    });
  };

  render() {
    return (
      <BrowserRouter>
        <Route
          path="/"
          exact
          render={props => <Dashboard data={this.state.leaseData} />}
        />
        <Route
          path="/lease/:id"
          render={props => (
            <Lease
              {...props}
              selected={this.state.selected}
              changeSelected={this.changeSelected}
            />
          )}
        />
      </BrowserRouter>
    );
  }
}

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

Dashboard.js

import React, { Component } from "react";
import { Link } from "react-router-dom";

class Dashboard extends Component {
  render() {
    let linkList = this.props.data.map((lease, index) => {
      return (
        <li key={index}>
          <Link to={`/lease/${lease.id}`}>
            <img
              src="https://cdn.edinarealty.com/media/2256/homepage-tiles_new-construction.jpg"
              alt="HTML5 Icon"
            />
          </Link>
        </li>
      );
    });

    return (
      <div>
        MAIN DASHBOARD
        <ul>{linkList}</ul>
      </div>
    );
  }
}

панель экспорта по умолчанию;

Lease.js

import React, { useEffect } from "react";
import { Link } from "react-router-dom";

const Lease = props => {
  useEffect(() => {
    const id = props.match.params.id;
    props.changeSelected(id);
  }, []);

  const { selected } = props;

  if (!selected) {
    return <div>Loading...</div>;
  } else {
    return (
      <div>
        <Link to="/">Back to home</Link>
        <h4>Id: {selected.id}</h4>
        <h4>Address: {selected.address}</h4>
        <h4>Rent: {selected.monthlyRent}</h4>
      </div>
    );
  }
};

export default Lease;

Основные ноты:

  1. App.js содержит наш маршрутизатор, данные аренды и выбранную аренду.
  2. Используя опору render, мы можем передавать данные из приложение-состояние, к компоненту Route. Для маршрута Dashboard мы передаем весь lease-data. Для маршрута аренды мы передаем changeSelected(), чтобы помочь получить выбранный объект аренды, и selected, который является найденным элементом. Кроме того, мы распространяем {... props}, чтобы получить доступ к реквизитам, таким как match и history.
  3. В Dashboard мы используем ту же логику генерации списка, которую вы настроили для отображения элементов.
  4. Когда вы щелкаете изображение и перенаправляетесь на компонент Lease, мы запускаем функцию changeSelected. Это происходит в useEffect(), мы используем props.match.params.id, чтобы получить идентификатор аренды (также в URL), к которой мы перешли по Link.
  5. Передайте это значение в changeSelected (), и оно обновит значение selected в состоянии приложения с помощью описанного объекта аренды в нашем списке.
  6. App.js повторно визуализируется (из-за изменения состояния) и передает значение состояния элемента selected в Lease, которое мы будем использовать для отображения информации об этом объекте аренды.

В целом, это чистый способ сделать это перед интеграцией Redux.

0 голосов
/ 11 июля 2019

песочница

Извлечение данных из Dashboard это даст нам возможность искать их по id, когда Lease компонент монтируется

Вы можете заменить егос вызовом API, когда вы реализуете бэкэнд

const data = [
  {
    id: 1,
    address: "18291 Rainbow Dr, Cool Springs CA 93102",
    monthlyRent: 4300
  },
  {
    id: 2,
    address: "2200 Stiller Dr, Las Vegas NV 96274",
    monthlyRent: 1500
  },
  {
    id: 3,
    address: "21626 Sleepy Hollow Ct, Walnut CA 91763",
    monthlyRent: 2400
  }
];

Извлекает leaseId из match.params.leaseId и ищет его, когда компонент монтируется, используя useEffect с leaseId в качестве зависимости

Когда у вас есть готовый API, вы можете просто заменить data.find вызовом API на leaseId

. Причина, по которой я ищу его при монтировании, заключается в том, что он даст намвозможность сразу перейти по URL-адресу без необходимости проходить через панель мониторинга для загрузки данных

const Lease = ({
  match: {
    params: { leaseId }
  }
}) => {
  const [leaseData, setLeaseData] = useState(null);

  useEffect(() => {
    setLeaseData(data.find(d => d.id.toString() === leaseId));
  }, [leaseId]);

  if (!leaseData) return null;

  return (
    <div>
      <h1>{leaseData.id}</h1>
      <p>{leaseData.address}</p>
      <p>{leaseData.monthlyRent}</p>
    </div>
  );
};

Когда URL-адрес равен /dashboard, используйте команду render для рендеринга основного Dashboard и создания Route путь к leaseId

const Dashboard = ({ match: { url } }) => {
  const linkList = data.map(lease => {
    return (
      <li key={lease.id}>
        <Link to={`${url}/${lease.id}`}>
          <img
            src="https://cdn.edinarealty.com/media/2256/homepage-tiles_new-construction.jpg"
            alt="HTML5 Icon"
          />
        </Link>
      </li>
    );
  });

  return (
    <Switch>
      <Route
        exact
        path={url}
        render={() => (
          <div>
            MAIN DASHBOARD
            <ul>{linkList}</ul>
          </div>
        )}
      />
      <Route path={`${url}/:leaseId`} component={Lease} />
    </Switch>
  );
};

const Home = () => (
  <div>
    <Link to="/dashboard">Dashboard</Link>
  </div>
);

const App = () => (
  <Router>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/dashboard" component={Dashboard} />
    </Switch>
  </Router>
);
0 голосов
/ 11 июля 2019

Вы можете использовать коммутатор маршрутизатора и сгенерировать свои маршруты аренды следующим образом:

import React, { Component } from 'react'
import { Switch, Link, Route } from 'react-router-dom'
import { Lease } from './Lease'

class Dashboard extends Component {
  constructor(props) {
    super(props)
    this.match = this.props.match

    this.leaseData = [
      {
        id: 1,
        address: '18291 Rainbow Dr, Cool Springs CA 93102',
        monthlyRent: 4300
      },
      {
        id: 2,
        address: '2200 Stiller Dr, Las Vegas NV 96274',
        monthlyRent: 1500
      },
      {
        id: 3,
        address: '21626 Sleepy Hollow Ct, Walnut CA 91763',
        monthlyRent: 2400
      }
    ]
  }

  render() {

    let linkList = this.leaseData.map(lease => {
      return (
        <li>
          <Link to={`${this.match.url}/${lease.id}`}>
          <img src="https://cdn.edinarealty.com/media/2256/homepage-tiles_new-construction.jpg" alt="HTML5 Icon"></img>
          </Link>
        </li>
      )
    })

    let leaseRoutes = this.leaseData.map(lease => <Route exact path={`${this.match.url}/${lease.id}`} render={<Lease data={lease}/>}/>)

    return (
      <div>
        MAIN DASHBOARD
        <ul>
         <li> {linkList} </li>
        </ul>
        <Switch>
            {leaseRoutes}
        </Switch>
        <Route path={`${this.match.url}/:lease-id`} render={<Lease data={}/>}/>
      </div>
    )
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...