Почему this.props.history не определен, несмотря на то, что использовал withRouter? - PullRequest
0 голосов
/ 06 февраля 2020

Я пытаюсь сделать this.props.history.push... в своем компоненте, но даже после того, как я убедился, что экспортирую его, используя withRouter, я все еще получаю эту ошибку:

Uncaught TypeError: Cannot read property 'push' of undefined

Я также убедился что родительский компонент, который использует это, также обернут внутри ProtectedRoute:

// мой компонент:

import React from 'react';
import { withRouter } from 'react-router-dom';
import { Link } from 'react-router-dom';

class UserIndexItem extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    this.play = this.play.bind(this);
  }

  handleClick(e) {
    if (!e.target.classList.contains("triangle")) {
      this.props.history.push(`/playlist/${this.props.playlist.id}`);    
    }
  }

  handleTrack(playlist) {
    // still going forward one, then back one, and then it plays normally...
    if (!playlist.payload.tracks) return;
    let tracks = Object.values(playlist.payload.tracks);
    let currentTrack = tracks[0];
    let nextTrack = tracks[1];
    this.props.receiveCurrentTrack(currentTrack);
    this.props.receiveNextTrack(nextTrack);
    this.props.receiveTitle(currentTrack.title);
    this.props.receiveArtist(currentTrack.artist);
    this.props.receiveAlbumId(currentTrack.album_id);
  }

  play() {
    const { playlist } = this.props;
    this.props.requestSinglePlaylist(this.props.playlist.id).then(playlist => this.handleTrack(playlist));
    this.props.receivePlaylistId(playlist.id);
  }

  render() {
    const { playlist } = this.props;

    return (
        <li>
          <div className="playlist-image" onClick={ this.handleClick }>
            <div className="play-button" onClick={ this.play }> 
              <div className="triangle right"></div> 
              <div className="circle"></div>
            </div>

            <div className="overlay"></div>
            <img src={playlist.photo_url} alt="Playlist thumbnail" onClick={ this.handleClick }/>
          </div>

          <div className="playlist-name">
            <Link to={`/playlist/${playlist.id}`}>{ playlist.title}</Link>
          </div>
        </li>
    );
  }
}

export default withRouter(UserIndexItem);  

// мой родительский компонент:

import React from 'react';
import UserIndexItem from './user_index_item';
import { selectTracksFromPlaylist } from '../../reducers/selectors';

class UserIndex extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    const { user, playlists } = this.props;

    return(
      <div className="user-index-container">
        <div className="header">
          <h1>{ user.username }</h1>
          <h2>Public Playlists</h2>
        </div>

        <div className="playlists">
          <ul>
            { playlists.map(playlist => 
              <UserIndexItem 
                key={ playlist.id } 
                playlist={ playlist }
                requestSinglePlaylist={ this.props.requestSinglePlaylist }
                receiveCurrentTrack={ this.props.receiveCurrentTrack }
                receiveNextTrack = { this.props.receiveNextTrack }
                receiveTitle={ this.props.receiveTitle }
                receiveArtist={ this.props.receiveArtist }
                receivePlaylistId={ this.props.receivePlaylistId }
                receiveAlbumId={ this.props.receiveAlbumId }
              />)
            }
          </ul>
        </div>
      </div>
    );
  }
}

export default UserIndex;

// мой маршрут, использующий родительский компонент:

<ProtectedRoute path="/users/:userId" component={UserIndex} />  

// моя реализация ProtectedRoute:

const Protected = ({ component: Component, path, loggedIn, exact }) => (
  <Route path={ path } exact={ exact } render={ (props) => (
    loggedIn ? (
      <Component {...props} />
    ) : (
      <Redirect to="/welcome" />
    )
  ) }/>
); 

Ответы [ 2 ]

0 голосов
/ 06 февраля 2020

Я думаю, что {... props} нужно также вызвать внутри UserIndexItem . Согласно моему пониманию внутри приложения. js вам нужно передать {... props} дочернему компоненту, в противном случае он не имеет родительских свойств

// this ProtectedRoute should change according to your requirement. I just put sample code 

const ProtectedRoute = ({ component: Component, ...rest }) => (
        <Route {...rest} render={(props) => (
            ? <Component {...props}  />
            : <Redirect to="/Login"/>
        )} />
)

<ProtectedRoute path="/users/:userId" component={UserIndex} /> 

// my parent component:
<UserIndexItem 
    key={ playlist.id } 
    playlist={ playlist }
    requestSinglePlaylist={ this.props.requestSinglePlaylist }
    receiveCurrentTrack={ this.props.receiveCurrentTrack }
    receiveNextTrack = { this.props.receiveNextTrack }
    receiveTitle={ this.props.receiveTitle }
    receiveArtist={ this.props.receiveArtist }
    receivePlaylistId={ this.props.receivePlaylistId }
    receiveAlbumId={ this.props.receiveAlbumId }
    {...this.props}
/>
0 голосов
/ 06 февраля 2020

Вы можете попробовать вот так:

<ProtectedRoute path="/users/:userId" component={props => <UserIndex {...props} />} />

Пожалуйста, дайте мне знать, если это работает.

Спасибо.

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