下一个js react app未定义的编译错误

时间:2018-11-25 23:38:42

标签: javascript reactjs next.js

我正在测试一个简单的next.js react应用程序,尽管当我尝试在localhost:300上访问它时出现错误。在news.js页面的第46行,我尝试测试state.articles是否为空,然后将props复制到其中,尽管next.js告诉我.length是未定义的。有谁知道为什么.length是未定义的?

错误如下; TypeError:无法读取未定义的属性“ length”

需要任何帮助

// This is the Link API
import Link from 'next/link';
import fetch from 'isomorphic-unfetch';
//import SearchForm from './components/SearchForm';

const apiKey = 'API-KEY';

const source = 'the-irish-times';

//build the url which will be sued to get the data
const url = `https://newsapi.org/v2/top-headlines? 
country=ie&category=sports&apiKey=${apiKey}`;


//getNews(url) is an async method which fetchs and 
returns data or and erroe
//from WWW Api
async function getNews(url){
//try fetch and catch any errors
try{
//make async call
const res = await fetch(url);
//get json data when it arrives
const data = await res.json();
//return json data
return(data);

  } catch (error){
return(error);
 }
}

// the news page definied as an ES6 Class
export default class News extends React.Component{
//constructor
//receive props and initialise state properties
constructor(props){
super(props)
this.state = {
  newsSource: "",
  url: "",
  atricles: []
  }
  } // end constructor
// render() method generates the page
render() {
//if state.articles is empty copy props to it
 **** THIS LINE
if(this.state.articles.length == 0){
  this.state.articles = this.props.articles;
}
return (
  <div>
    { /* display a title based on source */}
    <h3>{this.state.newsSource.split("-").join(" ")} 
</h3>
    <div>
    { /*iterate through artiles using array map */}
    { /* display author, publishedAT, image, desc and 
content */}
    { /* for each story also a link for more */}
    {this.state.articles.map((article, index) => (
      <section key = {index}>
    <h3>{article.title}</h3>
      <p className="author">{article.author} 
{article.publishedAt}</p>
      <img src={article.urlToImage} alt="artile 
image" className="img-article"></img>
      <p>{article.description}</p>
      <p>{article.content}</p>
      <p><Link href="/story"> <a>Read mor</a> </Link> 
</p>
      <p onClick = {this.test}>click..</p>
      </section>
    ))}
    </div>

   <style jsx>{`
   section {
     width: 50%;
     border: 1px solid grey;
     background-color: rgb(240, 248, 255);
     padding: 1em;
     margin: 1em;
   }

   .author {
     font-style: italic;
     font-size: 0.8em;
   }
   .img-article {
     max-width: 50%;
   }
   `}</style>
</div>

);
}//end render
}

//get initial data on server side using an AJAX call
// this will initialise the 'props' for the news page


async function getInitialProps(response){
//build the url which will be used to get the data
const initUrl = `https://newsapi.org/v2/top- 
headlines? 
sources=${defaultNewsSource}&apiKey=${apiKey}`;

//get news data from tje api url
const data = await getNews(initUrl);

//if the result contains an articles array then it is 
good so return articles
if(Array.isArray(data.articles)) {
return {
  articles: data.articles
}
}
// otherwise it contains an error, log and redirect 
to error page
else {
console.error(data)
 if(response) {
response.statusCode = 400
response.end(data.message);
}
}
} // end initial props

1 个答案:

答案 0 :(得分:0)

几个问题:

1。)状态属性名称输入错误

我相信您的意思是articles不是atricles

应该是

this.state = {
  newsSource: "",
  url: "",
  articles: []
}

不是

this.state = {
  newsSource: "",
  url: "",
  atricles: []
}

2。)改变不可变的React状态

在React中,我们用setState()更改状态。请记住,这是一个异步操作,由于您是在render函数中调用它的,因此它可能要等到下一次渲染时才会出现。

if(this.state.articles.length == 0){
  this.setState({ articles: this.props.articles });
}

class Application extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      articles: []
    };
  }

  render() {
    if(this.state.articles.length == 0){
      return (<div>Articles has no length</div>);
    }
  
    return (
      <div>
        Articles has a length.
      </div>
    );
  }
}

// Render it
ReactDOM.render(
  <Application/>,
  document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>