React Router Dom, обновление компонента на основе URL-адреса не выполняется - PullRequest
1 голос
/ 04 августа 2020

Я делаю приложение-реакцию для простого сайта электронной коммерции со следующими маршрутами:

<Switch>
  <Route exact path='/' component={Home} />
  <Route path='/login' component={Login} />
  <Route path='/signup' component={Signup} />
  <Route exact path='/top-products' component={TopProducts} />
  <Route path='/product/list' component={ProductList} />
  <Route path='/products/details/:id' component={ProductDetails} />
</Switch>

Все это работает хорошо, кроме /products/details/:id

import React, { Component } from 'react'
import Navbar from '../Navbar/Navbar'
import Parser from 'html-react-parser';
import './ProductDetails.css'
import Search from '../search/search';
import ProductCard from '../ProductCard/ProductCard'
import { Redirect } from 'react-router-dom';

export default class ProductDetails extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: true,
      data: [],
      recommendedData: [],
      id: this.props.match.id
    }
  }

  BASE_URL = 'https://upachar.com.np/'

  async componentDidMount() {
    console.log(this.props.match.params.id)
    const id = this.props.match.params.id
    const url = `${this.BASE_URL}api/v1/pharmacy/products/${this.props.match.params.id}`
    const response = await fetch(url)
    const data = await response.json()
    const recommendedUrl = this.BASE_URL + `api/v1/pharmacy/related-products/${this.props.match.params.id}`
    const recommendedResponse = await fetch(recommendedUrl)
    const recommendedData = await recommendedResponse.json()
    console.log('component did mount recommended product', recommendedData.data)
    this.setState({ data: data.data, loading: false, recommendedData: recommendedData.data })
  }

  componentDidUpdate(prevProps) {
    console.log('component did update')
    if (prevProps.match.params.id !== this.props.match.params.id) {
      console.log(prevProps.match.params.id, this.props.match.params.id)
      this.setState({ id: this.props.match.params.id })
    }
  }

  getImages = () => {
    return this.state.data.images.map(
      function (item, self) {
        const BASE_URL = this.BASE_URL.substring(0, this.BASE_URL.length - 1);
        return <img src={`${BASE_URL}${item}`} alt="image" style={{ 'height': '248px', 'width': '248px' }} />
      }, this)
  }

  getVariants = () => {
    return this.state.data.variants.map((item) => <div><ul>
      <p><b>Variant:</b> {item.name} <br /> <strong>Npr: </strong> {item.price}/{this.state.data.UOM.name}</p>
    </ul>
    </div>, this)
  }

  getRecommendedProducts() {
    return this.state.recommendedData.map((item) => {
      return <ProductCard
        title={item.name}
        UOM={item.UOM}
        price={item.price}
        image={item.thumbnails[0]}
        url={`/products/details/${item.id}`}
        manufacturer={item.manufacturer}
      />
    })
  }

  render() {
    if (this.state.loading) {
      return <h1>Loading...</h1>
    }
    return (
      <div>
        <Navbar />
        <Search />
        <div className="container">
          <h2 className='ProductDetails-title'>{this.state.data.name}</h2>
          <div className="row">
            <div className="col sm12 md6">
              <div className='ProductDetails-product-images'>{this.getImages()}</div>
            </div>

            <div className="col sm12 md3">
              <div className='ProductDetail-variants'>{this.getVariants()}</div>
            </div>
          </div>
          <div className='ProductDetails-details'>{Parser(this.state.data.details)}</div>
          <h4>Recommendations:</h4>
          <div className="ProductDetails-see-also">
            {this.getRecommendedProducts()}
          </div>
        </div>
      </div>
    )
  }
}

В этом компоненте detials, я получаю идентификатор через. this.props.match.params.id и в componentDidMount() я получаю сведения о продукте, а также сведения о рекомендуемых продуктах, и визуализирую их как компонент ProductCard. Проблема в том, что всякий раз, когда я нажимаю Link для перехода к новому продукту, URL-адрес изменяется, но в сведениях о продукте отображаются предыдущие сведения. Как обновить это, чтобы отобразить текущий продукт. Я попытался решить, используя ComponentDidUpdate, но все равно у меня та же проблема.

Компонент ProductCard

import React from 'react'
import { Link, Redirect } from 'react-router-dom'
import { v4 as uuidv4 } from 'uuid';

export default function DisplayCard({ title,
  UOM,
  price,
  image,
  url,
  manufacturer }) {
  const BASE_URL = 'http://www.upachar.com.np';

  return (
    <div className="card" style={{ 'width': '248px', height: '428px', 'margin': '20px' }}>
      <div className="card-image waves-effect waves-block waves-light" style={{ 'cursor': 'default' }}>
        <img className="card-image" src={`${BASE_URL}/${image}`} style={{ 'width': '248px', height: '248px' }} />
      </div>
      <Link to={url}>
        <div className="card-content">
          <span className="card-title grey-text text-darken-4">{title}</span>
          <div>By: {manufacturer}</div>
          <div>Price : NPR.{price} per {UOM} </div>
        </div>
      </Link>
    </div>
  )
}

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

PS. ссылка на github

1 Ответ

0 голосов
/ 05 августа 2020

Одно решение. В основном то, что я делаю, - это использование метода componentDidMount жизненного цикла для получения всех данных. Поэтому мне нужен был способ принудительно перемонтировать при изменении URL.

Я принудительно перемонтировал, используя key in <route.../>, так что мои новые маршруты похожи на

    <Switch>
       <Route exact path='/' component={Home} />
       <Route path='/login' component={Login} />
       <Route path='/signup' component={Signup} />
       <Route exact path='/top-products' component={TopProducts} />
       <Route path='/product/list' component={ProductList} />
       <Route exact path='/products/details/:id' render={(props) => 
       <ProductDetails key={Date.now()} {...props} id={props.match.params.id} />} />
       <Route render={(props) => <h1>404, Page Not Found!</h1> }/>
   </Switch>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...