Реагировать маршрутизатор и this.props: this.props.location.state не определена - PullRequest
0 голосов
/ 03 мая 2020

Я использую React Router в своем личном проекте, чтобы создать навигационное меню и перемещаться по нему. Я пытаюсь передать состояние от моего компонента APP к компоненту меню навигации, а затем к компоненту каждого раздела, но я бью стену и не могу понять, почему ...

Вот соответственно код для моего компонента App, компонента меню навигации и компонента Dealers (Dealers - это раздел, доступный в меню при нажатии кнопки «Dealers»).

Компонент приложения

import React from 'react';
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';
import './App.css';
import NavMenu from '../NavMenu/NavMenu';
import Dealers from '../Dealers/Dealers';
import About from '../About/About';
import Home from '../Home/Home';
import LogoHeartbeat from './heartbeat_logo.png';
import LogoLoveVinyl from './lvlogo.jpg';
import Discogs from '../../util/Discogs/Discogs';


class App extends React.Component{
  constructor(props){
    super(props);
    this.state={
      recoDetails:[],
      objectToRender:[],
      searchResults:[],
      dealersDb:[
      {
          name: 'Heartbeat Vinyl',
          location: 'Paris',
          address: '26 Rue Godefroy Cavaignac',
          open: 'from 12 pm to 8pm',
          holiday: 'Sunday',
          description:"Heartbeat Vinyl is a very cosy shop, offering a wide range of music. You'll find Jazz, Disco, House, Techno, Rock, Ambient, Soul, Funk, etc... One thing is sure, you can expect quality music from the owner Melik!",
          url: 'http://www.heartbeatvinyl.com/',
          logo: LogoHeartbeat,
          genre: ['Jazz','Rock','Disco','Funk','House','Japanese','Techno','Ambient'],
          id:'1',
          reco:['15179807','3447244','1559040'],
          recoInfo:[],
          video:[
              'https://www.youtube.com/embed/Zg1aJ0fhF2I',
              'https://www.youtube.com/embed/_C9ZNqNXODk',
              'https://www.youtube.com/embed/pgeTFQM1HV0',
              'https://www.youtube.com/embed/2ZJlYZEzYY0'
          ]
      },
      {
          name: 'Love Vinyl',
          location: 'London',
          address: '5 Pearson Street',
          open: 'from 11:30 am to 7pm',
          holiday: 'Monday',
          description:"Love Vinyl is an incredibly good record shop, offering a wide range of music. You'll find Jazz, Disco, House, Techno, Rock, Ambient, Soul, Funk, etc... One thing is sure, you can expect quality music from the owner Zaf!",
          url: 'https://www.lovevinyl.london/',
          logo: LogoLoveVinyl,
          genre: ['Jazz','Rock','Disco','Funk','House','Techno','Punk','Mods'],
          id:'2',
          reco:['2903013','1038746','13670323'],
          recoInfo:[]
      }
  ]
};
this.search=this.search.bind(this);
this.changeState=this.changeState.bind(this);
this.getRecoDetails=this.getRecoDetails.bind(this);

  }
  search(term){
    this.setState({
        searchResults: []
    });
let tempArray= [];
this.state.dealersDb.map(dealer=>{
    if(term===dealer.name || term===dealer.location || dealer.genre.find(element=>term===element)){
    tempArray.push(dealer);
    this.setState({
        searchResults: tempArray
    })
    }
});
}


    changeState(term) {
        let idToRender=[];
        this.state.dealersDb.map(dealer=>{
        if(term===dealer.id){
            idToRender=[dealer];
            }});
        let recoToFind=idToRender[0].reco;

        recoToFind.map(item=>{
            Discogs.search(item).then(response=>{
                if(idToRender[0].recoInfo.length<recoToFind.length){
                idToRender[0].recoInfo.push(response)}
                this.setState({
                    objectToRender: idToRender
                });
            })
        }) 
}

getRecoDetails(id){
    Discogs.search(id).then(response=>{
        this.state.recoDetails.push(response)
        return(
        this.setState({recoDetails: this.state.recoDetails
       }))});
    }

  render(){
    return(
<Router>
<div className="App">
  {console.log(this.state.dealersDb)}
    <NavMenu dealers={this.state.dealersDb} show={this.state.objectToRender} getId={this.changeState} searchResults={this.state.searchResults} search={this.search}/>
    <Route path='/' exact component={Home}/>
    <Route path='/Dealers' component={Dealers}/>
    <Route path='/About' component={About}/>
</div>
</Router>
);
  }
}


export default App;

Вот NavMenu компонент

import React from 'react';
import './NavMenu.css';
import Dealers from '../Dealers/Dealers';
import Home from '../Home/Home';
import {Link} from 'react-router-dom';

class NavMenu extends React.Component{
    render(){
        return(
<ul className="navigation">
    <Link to="/" exact>
    <button className="home button" onClick={<Home/>}>Home</button>
    </Link>
    <Link to={{
        pathname:'/Dealers',
        state:{
        dealers: this.props.dealers,
        show:this.props.show,
        getId:this.props.getId,
        searchResults:this.props.searchResults,
        search:this.props.search,
    }}}>
    {console.log(this.props.dealers)}
    <button className="dealr button" onClick={<Dealers/>}>Dealers</button>
    </Link>
    <Link to="/VideoArchives">
    <button className="videoArchives button">Video Archives</button>
    </Link>
    <Link to="/About">
    <button className="aboutUs button">About us</button>
    </Link>

</ul>)
    }
}

export default NavMenu;

и вот компонент Dealers

import React from 'react';
import SearchBarDealers from '../SearchBarDealers/SearchBarDealers.js';
import SearchDealersResults from '../SearchDealersResults/SearchDealersResults';
import DealerDetailsList from '../DealerDetailsList/DealerDetailsList';
import './Dealers.css';


class Dealers extends React.Component{

render(){
        return(

    <div>
        {console.log(this.props.location)}
        <div className="OriginalComponents">
        <SearchBarDealers onSearch={this.props.location.state.search}/>
        <div className="MainContainer">
            <div className="SDResults">
        <SearchDealersResults data={this.props.location.state.searchResults} getId={this.props.location.getId}/>
        </div>
        <div className="DDList">
        <DealerDetailsList show={this.props.location.state.show}/>
        </div>
        </div> 
        </div>
    </div>

        );
    }
}

export default Dealers;

Я провел несколько часов в Google, и, кажется, я объявляю все, как должно быть, пока я утешаю .log this.props.location в моем компоненте Dealers возвращает:

{pathname: "/Dealers", search: "", hash: "", state: undefined}
hash: ""
pathname: "/Dealers"
search: ""
state: undefined

Таким образом, это означает, что состояния не были правильно записаны на предыдущем шаге. Console.log в моем NavMenu для this.props.dealers возвращает ожидаемое значение, так что это означает, что когда я объявляю:

<Link to={{
        pathname:'/Dealers',
        state:{
        dealers: this.props.dealers,
        show:this.props.show,
        getId:this.props.getId,
        searchResults:this.props.searchResults,
        search:this.props.search,
    }}}>
    {console.log(this.props.dealers)}
    <button className="dealr button" onClick={<Dealers/>}>Dealers</button>
    </Link>

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

Может кто-нибудь помочь мне с этим? ^^; Что я тут не так делаю?

1 Ответ

0 голосов
/ 03 мая 2020

Чтобы сделать react-router реквизит (штат, местоположение и т. Д. c ...) доступным, вам нужно обернуть свой компонент с withRouter


 import { withRouter } from 'react-router-dom'

  ...

 export default withRouter(Dealers);
...