簡體   English   中英

在 React 中將狀態數組從一個組件傳遞到另一個組件

[英]Passing state array from one component to another in React

我的組件中有一個saved[]數組。 我想將此數據從一個組件傳遞到另一個組件。

我嘗試了以下方法:

<Home default path='/news' savedArticles={this.state.saved}/>

但這會引發錯誤,因為它說TypeError: Cannot read property 'saved' of null

所以這是擁有他們數據的組件。

新聞Main.js

import React, { Component } from 'react';
import '../news-main/news-main.css';
import News from '../news/news';
import NewsHero from '../news-hero/news-hero';
import Sports from '../sports/sports';

class NewsMain extends Component {
    render() {
        return (
            <div>
                <NewsHero />
                <News />
                <Sports />
            </div>
        )
    }
}
export default NewsMain;

數據來自NewsHero />組件。

新聞.hero.js

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 = headline => {
        this.setState(
         (prevState) => ({ saved: [...prevState.saved, headline] }),
          () => {
            console.log('Saved articles = ', this.state.saved);
            alert('Article saved');
            localStorage.setItem('saved', JSON.stringify(this.state.saved));
            localStorage.getItem('saved');
          });
      }

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

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

    componentDidMount() {
        this.setState({ loading: true, saved: localStorage.getItem('saved') ? JSON.parse(localStorage.getItem('saved')) : [] })
        fetch('https://newsapi.org/v2/everything?q=timbaland&domains=rollingstone.com,billboard.com&excludeDomains=townsquare.media&apiKey=8ee8c21b20d24b37856fc3ab1e22a1e5')
            .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(post)}>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;

我想將保存的數組傳遞給其他組件,例如

應用程序.js

import React, { Component } from 'react';
// import logo from './logo.svg';
import './App.css';
import Header from './header/header';
import NewsMain from './news-main/news-main';
import Footer from './footer/footer';
import Home from './home/home';
import { Router } from '@reach/router';

class App extends Component {

  render() {
    return (
      <div className="App">
        <Header />
        <div>
          <Router>
            <Home default path='/news' savedArticles={this.state.saved} />
            <NewsMain path='/news' />
          </Router>
        </div>
        <Footer title="Footer" />
      </div>
    )
  }
}
export default App;

有任何想法嗎?

在您的代碼中,在聲明任何狀態之前,您將屬性“保存”從對象“狀態”傳遞到 Home。

您的 App 組件的 render 方法中的 this.state 僅是您的 App 組件的狀態。 我相信您想使用 NewsHero 組件狀態中的屬性。 這個屬性只能在 NewsHero 組件中訪問,你必須以某種方式將它傳遞給 App 組件,然后你才能將它傳遞給 Home。

您還可以使用一些全局狀態或其他一些狀態庫,如 Redux,但顯然您必須折射給定的代碼

你還沒有在你的應用程序的任何地方啟動你的狀態,所以this.stateundefined

你的 app.js 應該是這樣的:

import React, { Component } from 'react';
// import logo from './logo.svg';
import './App.css';
import Header from './header/header';
import NewsMain from './news-main/news-main';
import Footer from './footer/footer';
import Home from './home/home';
import { Router } from '@reach/router';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {saved: []};
  }
  render() {
    return (
      <div className="App">
        <Header />
        <div>
          <Router>
            <Home default path='/news' savedArticles={this.state.saved} />
            <NewsMain path='/news' />
          </Router>
        </div>
        <Footer title="Footer" />
      </div>
    )
  }
}
export default App;

在此處查看https://it.reactjs.org/docs/state-and-lifecycle.html ,了解有關 reactjs 中狀態和生命周期的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM