Javascript 将对象从JSON rest api推送到不在React中工作的空数组中

Javascript 将对象从JSON rest api推送到不在React中工作的空数组中,javascript,reactjs,Javascript,Reactjs,我正在尝试将一个对象从RESTAPI的JSON响应推送到React中的空数组中,到目前为止,我的代码无法工作,我对React还相当陌生,所以看不出哪里出了问题?也许和这个州的功能有关?我得到一个错误: Cannot read property 'saved' of undefined 迄今为止的代码: import React, { Component } from 'react'; import './news-hero.css'; import Carousel from "react-m

我正在尝试将一个对象从RESTAPI的JSON响应推送到React中的空数组中,到目前为止,我的代码无法工作,我对React还相当陌生,所以看不出哪里出了问题?也许和这个州的功能有关?我得到一个错误:

Cannot read property 'saved' of undefined
迄今为止的代码:

import React, { Component } from 'react';
import './news-hero.css';
import Carousel from "react-multi-carousel";
import "react-multi-carousel/lib/styles.css";

const responsive = {
    superLargeDesktop: {
        breakpoint: { max: 4000, min: 3000 },
        items: 1,
    },
    desktop: {
        breakpoint: { max: 3000, min: 1024 },
        items: 1,
    },
    tablet: {
        breakpoint: { max: 1024, min: 464 },
        items: 1,
    },
    mobile: {
        breakpoint: { max: 464, min: 0 },
        items: 1,
    },
};

class NewsHero extends Component {
    state = {
        loading: false,
        data: [],
        headline: [],
        saved: []
    }

    saved() {
        this.saved.push(this.headline);
        //alert('this is saved kind of');
    }

    onError() {
        this.setState({
            imageUrl: "../assets/img-error.jpg"
        })
    }

    componentDidMount() {
        this.setState({ loading: true })
        fetch('https://newsapi.org/v2/everything?q=timbaland&domains=rollingstone.com,billboard.com&excludeDomains=townsquare.media&apiKey=8')
            .then(headline => headline.json())
            .then(headline => this.setState({ headline: headline.articles, loading: false }, () => console.log(headline.articles)))
    }

    render() {
        return (
            <div className="hero">
                <h2 className="text-left">News</h2>

                {this.state.loading
                    ? "loading..."
                    : <div>
                        <Carousel
                            additionalTransfrom={0}
                            showDots={true}
                            arrows={true}
                            autoPlaySpeed={3000}
                            autoPlay={false}
                            centerMode={false}
                            className="carousel-hero"
                            containerClass="container-with-dots"
                            dotListClass="dots"
                            draggable
                            focusOnSelect={false}
                            infinite
                            itemClass="carousel-top"
                            keyBoardControl
                            minimumTouchDrag={80}
                            renderButtonGroupOutside={false}
                            renderDotsOutside
                            responsive={responsive}>
                            {this.state.headline.map((post, indx) => {
                                return (
                                    <div className="text-left mt-5" key={indx}>
                                        <img className="media-img card-img-top card-img-hero" src={post.urlToImage} alt="Alt text"></img>
                                            <div className="card-body container hero-text-body">
                                                <h1 className="card-title hero-title text-truncate">{post.title}</h1>
                                                <button className="btn-primary btn mt-2 mb-4" onClick={this.saved}>Add this article</button>
                                                <p className="card-text">{post.description}</p>
                                                <a href={post.url} target="_blank" rel="noopener noreferrer">Read More</a>
                                            </div>
                                    </div>
                                )
                            })}
                        </Carousel>

                    </div>
                }
            </div>
        )
    }
}
export default NewsHero;
import React,{Component}来自'React';
导入“/news hero.css”;
从“react multi Carousel”导入转盘;
导入“react multi carousel/lib/styles.css”;
常数响应={
超大桌面:{
断点:{max:4000,min:3000},
项目:1,
},
桌面:{
断点:{max:3000,min:1024},
项目:1,
},
平板电脑:{
断点:{max:1024,min:464},
项目:1,
},
流动电话:{
断点:{max:464,min:0},
项目:1,
},
};
类NewsHero扩展组件{
状态={
加载:false,
数据:[],
标题:[],
已保存:[]
}
保存(){
this.saved.push(this.headline);
//警报(“这是保存的类型”);
}
onError(){
这是我的国家({
imageUrl:“../assets/img error.jpg”
})
}
componentDidMount(){
this.setState({loading:true})
取('https://newsapi.org/v2/everything?q=timbaland&domains=rollingstone.com,billboard.com&excludeddomains=townsquare.media&apiKey=8')
.then(headline=>headline.json())
.then(headline=>this.setState({headline:headline.articles,load:false},()=>console.log(headline.articles)))
}
render(){
返回(
新闻
{this.state.loading
“装载…”
: 
{this.state.headline.map((post,indx)=>{
返回(
{post.title}
添加这篇文章

{post.description}

) })} } ) } } 导出默认新闻英雄;
有什么想法和见解吗

无法读取未定义的属性“已保存”

您没有正确引用
此。对于
已保存的
标题
,请说明

无法读取未定义的属性“状态”

添加构造函数并将
绑定到已保存的
函数

constructor(props) {
  super(props);
  this.saved = this.saved.bind(this);
}

saved() {
    this.saved.push(this.headline);
    //alert('this is saved kind of');
}
或者将
保存的
定义为箭头函数,以绑定

saved = () => {
    this.saved.push(this.headline);
    //alert('this is saved kind of');
}
应该是

saved() {
  const { headline, saved } = this.state;
  this.setState({ saved: [...saved, headline] });
}

更新:保存特定的帖子/标题

我现在明白了,如果你想保存一个特定的标题,那么你需要更新你的
保存的
函数的签名以及你如何调用它

saved = headline => {
  this.setState(
    prevState => ({ saved: [...prevState.saved, headline] })
  );
}
当您将其作为回调调用时

<button
  className="btn-primary btn mt-2 mb-4"
  onClick={() => this.saved(post)} // pass the current post defined in the map callback
>
  Add this article
</button>
this.saved(post)}//传递映射回调中定义的当前post
>
添加这篇文章
一个关于命名的小注释,在代码中以相同的方式一致引用同一个“对象”,对提高可读性有很大帮助。例如,你如何引用标题、帖子和文章。选择一个并保持一致

this.state.headlines
=>
this.state.headlines.map(headline=>…

this.state.posts
=>
this.state.posts.map(post=>…

this.state.articles
=>
this.state.articles.map(article=>…

无法读取未定义的属性“已保存”

您没有正确引用
此。对于
已保存的
标题
,请说明

无法读取未定义的属性“状态”

添加构造函数并将
绑定到已保存的
函数

constructor(props) {
  super(props);
  this.saved = this.saved.bind(this);
}

saved() {
    this.saved.push(this.headline);
    //alert('this is saved kind of');
}
或者将
保存的
定义为箭头函数,以绑定

saved = () => {
    this.saved.push(this.headline);
    //alert('this is saved kind of');
}
应该是

saved() {
  const { headline, saved } = this.state;
  this.setState({ saved: [...saved, headline] });
}

更新:保存特定的帖子/标题

我现在明白了,如果你想保存一个特定的标题,那么你需要更新你的
保存的
函数的签名以及你如何调用它

saved = headline => {
  this.setState(
    prevState => ({ saved: [...prevState.saved, headline] })
  );
}
当您将其作为回调调用时

<button
  className="btn-primary btn mt-2 mb-4"
  onClick={() => this.saved(post)} // pass the current post defined in the map callback
>
  Add this article
</button>
this.saved(post)}//传递映射回调中定义的当前post
>
添加这篇文章
一个关于命名的小评论,在整个代码中以相同的方式一致地引用同一个“对象”,对提高可读性有很大帮助。例如,如何引用标题、帖子和文章。选择一个并保持一致

this.state.headlines
=>
this.state.headlines.map(headline=>…

this.state.posts
=>
this.state.posts.map(post=>…

this.state.articles
=>
this.state.articles.map(article=>…

saved(){
this.saved.push(this.headline);
//警报(“这是保存的类型”);
}
如果不编写这样的构造函数,就无法定义这样的类方法:

class新闻英雄扩展组件{
建造师(道具){
超级(道具)
this.saved=this.saved.bind(this)
}
…你写的其他东西
}
如果不这样做,您的
保存的
函数就不会绑定到类的实例。是的,这很愚蠢,但在javasript中类方法就是这样工作的。另一个选项是使用箭头函数,如果
,它会保留上下文:

saved=()=>{
this.saved.push(this.headline);
//警报('这是