简体   繁体   English

当我在链接之间切换并根据标签值获取数据时,如何设置父组件的状态

[英]How set the state of parent component when i toggle between the links and fetch the data based on tag value

Task is to fetch data from api when toggle between tags 任务是在标记之间切换时从api获取数据

When click on the link it calls the api service but state of feeds is not updated but it throws below warning 当单击链接时,它调用api服务,但提要的状态未更新,但低于警告

jQuery.Deferred exception: Cannot read property 'setState' of undefined TypeError: Cannot read property 'setState' of undefined jQuery.Deferred异常:无法读取未定义类型的属性“ setState”:无法读取未定义的属性“ setState”

My github repo 我的github回购

https://github.com/dolphine4u/demo-app https://github.com/dolphine4u/demo-app

APP component APP组件

import React from 'react';
import {FetchData} from "../service/flickerApi.service";
import Header from "./header/header.component";
import Navigation from "./navigation/navigation.component";
import ProductList from "./products/products.component";
import Footer from "./footer/footer.component";


class App extends React.Component {

    constructor() {
        super()
        this.state = {
            feeds: [],
            favorites:[]
        };

        this.addToFavorites = this.addToFavorites.bind(this);
    }

    handleChange( value ) {
        this.setState( { feeds: value })
    }

    addToFavorites(id) {
        const {feeds ,favorites} = this.state;
        const findId = feeds.filter(item => {
            return item.id === id;
        })

        favorites.push(findId)
        console.log(favorites)
      // localStorage.setItem('favorite', JSON.stringify(this.state.favorites));
        this.setState({
            feeds: favorites
        });


    }


   /* componentWillMount(){
        let LoadFeeds =  localStorage.getItem('FlickerFeeds');

        LoadFeeds && this.setState({
            feeds: JSON.parse(LoadFeeds)
        })
    }*/

    componentDidMount() {
        FetchData.call(this);
    }


   /* componentWillUpdate(nextprops, nextState){
        localStorage.setItem('FlickerFeeds', JSON.stringify(nextState.feeds))
    }
*/
    render() {
        const {feeds} = this.state;
        const productList = feeds.map((item,index) => {
            return <ProductList
                key={index}
                title={item.title}
                image={item.src}
                id={item.id}
                author={item.author}
                date={item.created}
                update={this.addToFavorites}
            />
        })

        return ([
            <Header key="header"/>,

            <Navigation key="navigation" />,

            <section key="productList">
                <div className="container">
                    <div className="row row-eq-height">
                        {productList}
                    </div>
                </div>
            </section>,

            <Footer key="footer"/>
        ]);
    }

}

export default App;

Navigation component 导航组件

import React from 'react';
import Link from "./link.component";
import './navigation.css';

class Navigation extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            tags: [
                {tag:"kittens"},
                {tag:"dogs"},
                {tag:"lion"},
                {tag:"tiger"},
                {tag:"leapord"}]
        };
    }

    render() {
        const {tags} = this.state;
        const tagList = tags.map(item => {
            return <Link
                key={item.tag}
                tag={item.tag}
            />
        })
        return (
            <nav className="nav">
                <div className="container">
                    <ul className="nav-bar">
                        {tagList}
                    </ul>
                </div>
            </nav>
        );
    }
}

export default Navigation;

Link Component 链接组件

import React from 'react';
import {FetchData} from "../../service/flickerApi.service";

class Link extends React.Component {
    constructor(props) {
        super(props)
        this.onClick = this.onClick.bind(this);
    }
    onClick(e) {
        FetchData(this.props.tag);
    }

    render() {
        return (
            <li><a href="#" onClick={this.onClick}>{this.props.tag}</a></li>

        );
    }
}

export default Link;

product component 产品组成

import React from 'react';
import './product.css';

class ProductList extends React.Component {
    constructor(props) {
        super(props);
        this.onClick = this.onClick.bind(this);
    }

    onClick(e) {
        this.props.update(this.props.id);
    }

    render() {
        return (
            <div className="product-column">
                <div className="product-item">
                    <div className="product-content">
                        <div className="product-author">
                            <strong>Author: </strong>{this.props.author}
                        </div>
                        {/*<div className="product-image" style={{backgroundImage: "url(" + this.props.image + ")"}}/>*/}
                    </div>
                    <div className="product-content">
                        <div className="product-date">
                            Created Date: {this.props.date}
                        </div>
                        <h3 className="product-title">{this.props.title}</h3>
                        <button className="product-btn" onClick={this.onClick}>
                            Add to Favourites
                        </button>
                    </div>
                </div>
                {/*<div className="product-description" dangerouslySetInnerHTML={{__html: this.props.description}}>
                        </div>*/}
            </div>

        );
    }
}

export default ProductList;

Api service api服务

import $ from "jquery";
import {getLastPartOfUrl, formatDate, removeUrl, getString} from "../helpers/helper";

export function FetchData(tag) {

    const URL = "https://api.flickr.com/services/feeds/photos_public.gne?format=json&jsoncallback=?"
    const SUFFIX_SMALL_240 = "_m";
    const SUFFIX_SMALL_320 = "_n";
     $.getJSON({
        url : URL,
         data: {
             tags: tag
         }
     })
        .then(response => {
            let list= response.items.map(item => ({
                title: removeUrl(item.title),
                id: getLastPartOfUrl(item.link),
                description: item.description,
                link: item.link,
                src: item.media.m.replace(SUFFIX_SMALL_240, SUFFIX_SMALL_320),
                author: getString(item.author),
                created: formatDate(item.published),
                tags: item.tags,
                fav: false
            }));

            this.setState({
                feeds: list
            })

        }).catch(function(error){
            console.log(error);
     });
}

You're trying to call this.addToFavorites from a click handler that is not even bound to this . 您正在尝试从尚未绑定到this的点击处理程序调用this.addToFavorites I think two changes are needed for this to work: 我认为需要进行两项更改才能起作用:

  1. In App component, change the addFavorites function to an arrow function so it gets the context this : 在App组件中,将addFavorites函数更改为arrow函数,以便获取this

     addToFavorites = id => { ... 
  2. Same in ProductList component for the click handler: 与点击处理程序的ProductList组件相同:

     onClick = () => { this.props.update(this.props.id); } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何根据子组件复选框值设置父组件 state? - How can I set the parent component state based on children component checkbox value? 在父组件之间切换布尔状态 - Toggle boolean state between from parent component 如何根据状态值在反应中获取数据 - how to fetch data in react based on the state value 在 React 中,父组件如何从响应中设置状态以及在子组件中执行的异步获取功能? - In React, how can a parent component set state from the response an async fetch function performed in a child component? 当我有可重用的React组件,父组件或子组件(可重用组件)时,在哪里在React中获取数据 - Where to fetch data in React when I have a reusable react component, Parent or Child component (reusable component) 如何根据父组件的 API 调用设置子组件的初始 state? - How to set initial state of child component based on parent component's API call? 如何在基于 3 个不同 state 元素的组件中切换 css class - How to toggle css class in a component based on 3 different state elements 如何使用jquery切换2个链接(标记)? - How do I toggle 2 links (a tag) using jquery? Vue:如何根据父数据渲染动态组件? - Vue: How do I render a dynamic component based on parent data? 如何在页面加载时基于锚标记在div之间切换? - How do I toggle between divs based on anchor tag on page load?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM