[英]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: 我认为需要进行两项更改才能起作用:
In App component, change the addFavorites
function to an arrow function so it gets the context this
: 在App组件中,将
addFavorites
函数更改为arrow函数,以便获取this
:
addToFavorites = id => { ...
Same in ProductList
component for the click handler: 与点击处理程序的
ProductList
组件相同:
onClick = () => { this.props.update(this.props.id); }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.