首页 > 解决方案 > 尽管使用了 withRouter,为什么 this.props.history 未定义?

问题描述

我正在尝试this.props.history.push...在我的组件中执行此操作,但即使在确保使用它导出它之后,withRouter我仍然会收到此错误:

Uncaught TypeError: Cannot read property 'push' of undefined

我还确保使用它的父组件也包含在 aProtectedRoute中:

// 我的组件:

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" />
    )
  ) }/>
); 

标签: reactjsredux

解决方案


你可以这样尝试:

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

请让我知道这是否有效。

谢谢。


推荐阅读