代码之家  ›  专栏  ›  技术社区  ›  Cody Lemons

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

  •  1
  • Cody Lemons  · 技术社区  · 6 年前

    我不知道为什么我的应用程序总是说未定义。错误源于相册的第21行。js公司: <img id="album-cover-art" src={this.state.album.albumCover}/> 我想我需要补充 this.state.album 某处,但我不知道在哪里。

    指数js公司:

    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();
    

    应用程序。js公司:

    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;
    

    着陆。js公司:

    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;
    

    图书馆js公司:

    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;
    

    相册。js公司

    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' }
        ]
    }];
    

    专辑js公司:

    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;
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Aaqib    6 年前

    在将道具传递给 <Album /> 你应该检查一下 <Route /> 用于匹配 slug 即: albumData.find() 所以在里面 App.js 渲染前 <Album> :

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

    因此,您的相册组件路径应该如下所示:

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

    确保移动 albumData 应用程序内部。js(相应地修复路径)

    import albumData from './../data/albums';
    

    利用 <Switch> 并将标头逻辑移动到另一个标头组件中,而不是主 应用程序。js公司

    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 > 所以你的专辑。js现在应该是:

    从“React”导入React,{Component};

    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.album then this.props.album.releaseInfo 应该是公正的 releaseInfo (您可以对此进行相应修改)