【问题标题】:Cannot read property 'key' of undefined react无法读取未定义反应的属性“键”
【发布时间】:2020-09-07 00:06:41
【问题描述】:

Home.js 组件

import React, { Component } from 'react';
import axios from 'axios';

import styles from './home.module.css';
import TurnArrow from '../../assets/images/turn.svg';
import LoadingGif from '../../assets/images/loading.gif';

import SearchBox from '../SearchBox/SearchBox';
import RepoItem from '../RepoItem/RepoItem';

class Home extends Component {
    constructor(props) {
        super(props)
        
        this.state = {
            repos: [],
            inputValue: "",
            isEmptySearch: false,
            isLoading: false,
            per_page: 100,
            limit: 10,
            total_count: null,
            showMore: true,
            index: 10,
            dataLoaded: false,
            reposLength: null
        }

        this.myRef = React.createRef();

        this.updateInputValue = this.updateInputValue.bind(this);
        this.fetchRepos = this.fetchRepos.bind(this);
        this.handleClick = this.handleClick.bind(this);
        this.handleKeyPress = this.handleKeyPress.bind(this);
    }

    scrollToMyRef() {
        window.scrollTo(0, this.myRef.current.offsetTop);
    }

    updateInputValue(e) {
        this.setState({
            inputValue: e.target.value
        });
    }

    fetchRepos() {
        if(this.state.inputValue.trim() === "" || this.state.inputValue.trim() === null) {
            return this.setState({ isEmptySearch: true});
        } 
        
        this.setState({ 
            isEmptySearch: false,
            isLoading: true
        });

        axios.get(`https://api.github.com/search/repositories?q=${this.state.inputValue}&per_page=100`)
            .then(response => {
                this.setState({ 
                    total_count: response.data.total_count, 
                    repos: response.data.items,
                    isLoading: false,
                    dataLoaded: true,
                    reposLength: response.data.items.length
                 })

                 return this.scrollToMyRef();
                
            })
            .catch(err => console.log(err));
    }

    handleClick() {
        this.fetchRepos();
    }

    handleKeyPress(e) {
        if(e.key === "Enter") {
            this.fetchRepos();
        }

        return
    }

    render() {
        let { repos, isEmptySearch, total_count, isLoading } = this.state;
        return (
            <>
            <header className={styles.hero}>
                <div className="container">
                    <div className={styles.innerHero}>
                        <div>
                            <h1>Welcome to GIT M<span>EƎ</span>T</h1>
                            <p>Discover millions of github repositories <br></br>right here, right now.</p>
                            <p>Start by using the search box on the right.</p>
                        </div>
                        <div className={styles.searchBox}>
                            <SearchBox>
                                <img src={TurnArrow} alt="arrow pointing to search button" />
                                <h1>Search Repos</h1>
                                <input onKeyPress={this.handleKeyPress} onChange={this.updateInputValue} type="text" name="search" id="search" placeholder="E.g. 'ultra amazing html h1 tag...'" autoComplete="off" required />
                                <button disabled={ isLoading ? true : false } onClick={this.handleClick}>{ isLoading ? <img src={LoadingGif} alt="loading..." /> : "Search" }</button>
                                { isEmptySearch ? <p className={styles.errorMessage}>Please enter something first!</p> : "" }
                            </SearchBox>
                        </div>
                    </div>
                </div>
            </header>
            <main>
                {this.state.dataLoaded ? <RepoItem ref={this.myRef} total_count={total_count} repos={repos}/> : "" }
                <button className={styles.loadMore}>Load More</button> 
                
            </main>
            </>
        );
    }
}

export default Home;

RepoList 组件

import React, { useState, useEffect } from 'react'

import styles from './repo_item.module.css';

import Footer from '../Footer/Footer';

const RepoList = React.forwardRef((props, ref) => {

    const [repos, setRepos] = useState([props.repos]);

    useEffect(() => {
        setRepos(props.repos);
    }, [props.repos]);

    return (
        <>
       <div className="container">
           <div className={styles.infoWrap}>
               <h2>Results</h2>
                <p>Found {props.total_count} results</p>
           </div>
           <div ref={ref} className={styles.repoWrap}>
                {repos.length > 0 ? repos.map((item,index) => {
                    console.log(item);
                    return (
                        <div key={index} className={styles.repoItem}>
                            <div className={styles.userProfile}>
                                
                            </div>
                            { item.name && item.name.length > 20 ? item.name.substring(0,20) + "..." : item.name }
                            { item.license.key }
                        </div>
                    );
                }) : ""}
           </div>
       </div>
       <Footer />
       </>
    );
})

export default RepoList;

为什么... item.license.key 不起作用但 item.name 起作用......帮助。 我觉得我搞砸了 Home 和 repo 组件之间的连接,但我自己看不到错误。这就是我在这里发布它的原因,也许有人会更快地注意到这个问题。

提前感谢您,我已尝试检查项目及其内容,但每次都收到相同的错误。

【问题讨论】:

  • 你能分享代码属性吗,你分享了 RepoItem 组件但代号是 RepoList。
  • 是的....它的 RepoList。我仍然无法编辑它。

标签: reactjs api github axios


【解决方案1】:

在发现很多问题不在代码中后,您从 API 获取数据,例如 https://api.github.com/search/repositories?q=bootstrap&per_page=100

license 属性为 null,因此您遇到了问题。

检查空条件 {item.license &amp;&amp; item.license.key}

API 调用响应:

{
   "total_count":276072,
   "incomplete_results":false,
   "items":[
      {
         "id":2126244,
         "node_id":"MDEwOlJlcG9zaXRvcnkyMTI2MjQ0",
         "name":"bootstrap",
         .....
         "license":{
            "key":"mit",
            "name":"MIT License",
            "spdx_id":"MIT",
            "url":"https://api.github.com/licenses/mit",
            "node_id":"MDc6TGljZW5zZTEz"
         },
        ......
      },
      {
         "id":5689093,
         "node_id":"MDEwOlJlcG9zaXRvcnk1Njg5MDkz",
         "name":"android-bootstrap",
         .....
         "license":null,
         .....
      }
   ]
}

【讨论】:

  • 正如我所提到的,我已经尝试过检查属性。它不仅与许可证有关,而且与任何比 1 级更深的属性有关,例如所有者、许可证等……但最上面的那些,例如 name、full_name 等都很好。
猜你喜欢
  • 1970-01-01
  • 2022-10-08
  • 1970-01-01
  • 2022-01-25
  • 1970-01-01
  • 2022-09-27
  • 2021-11-20
  • 2020-09-07
  • 2021-06-22
相关资源
最近更新 更多