首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TypeError:无法读取未定义的slug属性

TypeError:无法读取未定义的slug属性
EN

Stack Overflow用户
提问于 2018-02-25 04:37:12
回答 1查看 3.4K关注 0票数 1

我不确定为什么我的应用程序一直显示未定义。错误起源于Album.js:<img id="album-cover-art" src={this.state.album.albumCover}/>的第21行。我认为我需要在某个地方添加this.state.album,但我不确定在哪里。

Index.js:

代码语言:javascript
复制
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
  , document.getElementById('root'));
registerServiceWorker();

App.js:

代码语言:javascript
复制
import React, { Component } from 'react';
import { Route, Link } from 'react-router-dom';
import './App.css';
import Landing from './components/Landing';
import Library from './components/Library';
import Album from './components/Album';

class App extends Component {
  render() {
    return (
      <div className="App">
      <header>
        <nav>
          <Link to='/'>Landing</Link>
          <Link to='/library'>Library</Link>

        </nav>
        <h1>Bloc Jams</h1>
      </header>
        <main>
          <Route exact path="/" component={Landing} />
          <Route path="/library" component={Library} />
          <Route path="/album/:slug" component={Album} />
        </main>
      </div>
    );
  }
}

export default App;

Landing.js:

代码语言:javascript
复制
import React from 'react';

const Landing = () => (
  <section className="landing">
  <h1 className="hero-title">Turn the music up!</h1>

  <section className="selling-points">
    <div className="point">
      <h2 className="point-title">Choose your music</h2>
      <p className="point-description">The world is full of music; 
why should you have to listen to music that someone else chose?</p>
    </div>
    <div className="point">
      <h2 className="point-title">Unlimited, streaming, ad-free</h2>
      <p className="point-description">No arbitrary limits. No 
distractions.</p>
    </div>
    <div className="point">
      <h2 className="point-title">Mobile enabled</h2>
      <p className="point-description">Listen to your music on the 
go. This streaming service is available on all mobile platforms.</p>
    </div>
  </section>
  </section>
);


export default Landing;

Library.js:

代码语言:javascript
复制
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import albumData from './../data/albums';

class Library extends Component {
  constructor(props) {
    super(props);
    this.state = { albums: albumData };
  }
  render() {
    return (
      <section className='library'>
      {
        this.state.albums.map( (album, index) =>
          <Link to={`/album/${album.slug}`} key={index}>
            <img src={album.albumCover} alt={album.title} />
            <div>{album.title}</div>
            <div>{album.artist}</div>
            <div>{album.songs.length} songs</div>
          </Link>
        )
      }
      </section>
    );
  }
}


export default Library;

albums.js

代码语言:javascript
复制
export default [{
  title: 'The Colors',
  artist: 'Pablo Picasso',
  releaseInfo: '1909 Spanish Records',
  albumCover: '/assets/images/album_covers/01.jpg',
  slug: 'the-colors',
  songs: [
      { title: 'Blue', duration: '161.71', audioSrc: 
'/assets/music/blue.mp3' },
      { title: 'Green', duration: '103.96', audioSrc: 
'/assets/music/green.mp3' },
      { title: 'Red', duration: '268.45', audioSrc: 
'/assets/music/red.mp3' },
      { title: 'Pink', duration: '153.14', audioSrc: 
'/assets/music/pink.mp3' },
      { title: 'Magenta', duration: '374.22', audioSrc: 
'/assets/music/magenta.mp3' }
  ]
}, {
    title: 'The Telephone',
    artist: 'Guglielmo Marconi',
    releaseInfo: '1909 EM',
    albumCover: '/assets/images/album_covers/02.jpg',
    slug: 'the-telephone',
    songs: [
      { title: 'Blue', duration: '161.71', audioSrc: 
'/assets/music/blue.mp3' },
      { title: 'Green', duration: '103.96', audioSrc: 
'/assets/music/green.mp3' },
      { title: 'Red', duration: '268.45', audioSrc: 
'/assets/music/red.mp3' },
      { title: 'Pink', duration: '153.14', audioSrc: 
'/assets/music/pink.mp3' },
      { title: 'Magenta', duration: '374.22', audioSrc: 
'/assets/music/magenta.mp3' }
    ]
}];

Album.js:

代码语言:javascript
复制
import React, { Component } from 'react';
import albumData from './../data/albums';

class Album extends Component {
  constructor(props) {
    super(props);

    const album = albumData.find( music => {
      return album.slug === this.props.match.params.slug
    });

    this.state = {
      album: album
    };
  }

  render() {
    return (
      <section className="album">
        <section id="album-info">
        <img id="album-cover-art" src={this.state.album.albumCover}/>
        <div className="album-details">
          <h1 id="album-title">{this.state.album.title}</h1>
          <h2 className="artist">{this.state.album.artist}</h2>
         <div id="release-info">{this.state.album.releaseInfo} </div>
        </div>
      </section>
      <table id="song-list">
          <colgroup>
            <col id="song-number-column" />
            <col id="song-title-column" />
            <col id="song-duration-column" />
          </colgroup>
          <tbody>
          </tbody>
      </table>
      </section>
    );
  }
}

export default Album;
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-25 05:17:34

在将道具传递给<Album />之前,您应该检查<Route />内部是否匹配slug,即:albumData.find(),因此在呈现<Album>之前,请在App.js内部执行以下操作:

代码语言:javascript
复制
        component={ props => {
        const album = albumData.find(music => 
        music.slug === props.match.params.slug
        );

所以你的相册组件路由应该是这样的:

代码语言:javascript
复制
      <Route
        exact
        path="/album/:slug" 
        component={ props => {
        const album = albumData.find(music => 
        music.slug === props.match.params.slug
        );
      return (<Album album={album} {...props}>);
      }}
      />

确保在App.js中移动albumData (相应地修复路径)

代码语言:javascript
复制
import albumData from './../data/albums';

使用并将头逻辑移动到另一个头组件中,而不是主App.js

代码语言:javascript
复制
import React, { Component } from 'react';
import { Route, Link , Switch } from 'react-router-dom';
import './App.css';
import Landing from './components/Landing';
import Library from './components/Library';
import Album from './components/Album';
import albumData from './../data/albums';

class App extends Component {
  render() {
    return (
      <div className="App">
        <Switch>
          <Route exact path="/" component={Landing} />
          <Route path="/library" component={Library} />

          <Route
            exact
            path="/album/:slug" 
            component={ props => {
            const album = albumData.find(music => 
            music.slug === props.match.params.slug
            );

          return (<Album album={album} {...props}>);

          }}
          />
          </Switch>
      </div>
    );
  }
}

export default App;

现在在你的Album.js中,你不需要声明任何构造函数,因为它只是作为一个props传递给<Album >,所以你的Album.js现在应该是:

从‘react’导入React,{ Component };

代码语言:javascript
复制
class Album extends Component {

  render() {
    return (
      <section className="album">
        <section id="album-info">
        <img id="album-cover-art" src={this.props.album.albumCover}/>
        <div className="album-details">
          <h1 id="album-title">{this.props.album.title}</h1>
          <h2 className="artist">{this.props.album.artist}</h2>
         <div id="release-info">{this.props.album.releaseInfo} </div>
        </div>
      </section>
      <table id="song-list">
          <colgroup>
            <col id="song-number-column" />
            <col id="song-title-column" />
            <col id="song-duration-column" />
          </colgroup>
          <tbody>
          </tbody>
      </table>
      </section>
    );
  }
}
export default Album;

或者你可以使用析构const { releaseInfo } = this.props.albumthen this.props.album.releaseInfo应该只是releaseInfo (你可以相应地修改它)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48967357

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档