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

Sol*_*ole 1 javascript reactjs

我正在尝试将来自rest api的JSON响应中的对象推送到React中的空数组中,到目前为止我的代码无法正常工作,我对React还很陌生,所以看不出我哪里出错了?也许与状态中的功能有关?我收到错误:

Cannot read property 'saved' of undefined
Run Code Online (Sandbox Code Playgroud)

到目前为止的代码:

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;
Run Code Online (Sandbox Code Playgroud)

任何想法和见解?

Dre*_*ese 5

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

你是不是正确引用this.statesavedheadline

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

添加一个构造函数并绑定this到您的saved函数。

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

saved() {
    this.saved.push(this.headline);
    //alert('this is saved kind of');
}
Run Code Online (Sandbox Code Playgroud)

或者定义saved为一个箭头函数来绑定this

saved = () => {
    this.saved.push(this.headline);
    //alert('this is saved kind of');
}
Run Code Online (Sandbox Code Playgroud)

应该

saved() {
  const { headline, saved } = this.state;
  this.setState({ saved: [...saved, headline] });
}
Run Code Online (Sandbox Code Playgroud)

或者

saved = () => {
  const { headline, saved } = this.state;
  this.setState({ saved: [...saved, headline] });
}
Run Code Online (Sandbox Code Playgroud)

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

我现在看,如果你想保存特定的标题,那么你需要更新你的签名saved功能你怎么称呼它。

saved = headline => {
  this.setState(
    prevState => ({ saved: [...prevState.saved, headline] })
  );
}
Run Code Online (Sandbox Code Playgroud)

当您将其作为回调调用时

<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>
Run Code Online (Sandbox Code Playgroud)

关于命名,始终引用相同的“对象”,整个代码相同的方法之一轻微的评论很长的路要走,帮助可读性。IE 如何引用标题、帖子和文章。选择一个并保持一致。

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

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

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