Here is my store:
import helper from './../../helpers/RestHelpers.js';
var posts = [];
class PostStore {
constructor() {
helper.get('/api/posts')
.then((data) => {
posts = data;
console.log(posts);
}
);
}
getPosts() {
return posts;
}
};
export default new PostStore();
When I console.log posts from within the helper function, I get the correct data. But when I console.log from the component, the array of posts is empty.
Here is my component:
import React from 'react';
import postStore from '../stores/PostStore';
class Home extends React.Component {
constructor() {
super();
this.state = {
posts: postStore.getPosts()
}
console.log(this.state.posts);
}
render() {
return (
<div className="welcome">
{this.state.posts.map(function(post, index) {
return (
<PostItem post={post} key={"post " + index} />
)
})
}
</div>
)
}
}
class PostItem extends React.Component {
render() {
return <div>{this.props.post.postName}</div>;
}
}
export default Home;
I wouldn't use your PostStore as-is. Instead just use your helper directly like so:
import React from 'react';
// import your helper!
class Home extends React.Component {
componentDidMount() {
helper.get('/api/posts').then((data) => {
this.setState({posts: data})
});
}
render() {
return (
<div className="welcome">
{this.state.posts.map((post, idx) => <PostItem post={post} key={"post " + idx} />)}
</div>
)
}
}
Related
1.Can someone help me where i made a thing wrong?
2.the component i am mapping the state to its properties but i still get this
error"mapStateToProps is not defined"
this is the whole component below. the error reads "mapStateToProps not defined"
import React, {Component} from 'react';
import Icon from 'react-native-vector-icons/EvilIcons';
import { loadInitialPosts} from './actions';
import {connect } from 'react-redux';
import _ from 'lodash';
import {View, StyleSheet,FlatList} from 'react-native';
import PostItem from './PostItem';
import PostDetail from './PostDetail';
class PostsList extends Component {
componentWillMount() {
this.props.loadInitialPosts();
}
renderItem({item}){
return <PostItem posts = { item } />;
}
renderInitialView(){
if(this.props.postDetailView === true){
return(
<PostDetail />
);
}
else{
return(
<FlatList
data={this.props.posts}
renderItem={this.renderItem} />
)}
}
render(){
return(
<View style={styles.list}>
{this.renderInitialView()}
</View>
);
}
}
const mapStateToProps = state => {
const posts = _.map(state.posts, (val, id) =>
{
return { ...val, id};
});
return{
posts: posts,
postDetailView: state.postDetailView,
};
}
export default connect(mapStateToProps, { loadInitialPosts })(PostsList)
1.This is the action that dispatches the data
export const loadInitialPosts = () => {
return function(dispatch){
return axios.get(apiHost
+"/api/get_posts?
count=20")
.then((response) => {
dispatch({ type:
'INITIAL_POSTS_FETCH', payload:
response.data.posts});
}).catch((err) => {
console.log(err);
});
};
};
mapStateToProps sits outside of the class before export default connect(mapStateToProps)(SomeClass)
class SomeClass extends React.Component {
...
}
const mapStateToProps = state => {
const posts = _.map(state.posts, (val, id) => {
return { ...val,
id
};
});
return {
posts: posts,
postDetailView: state.postDetailView,
};
}
To eliminate the possibility of mapStateToProps being undefined, consider defining the mapStateToProps directly in the call to connect() like this:
class PostsList extends React.Component {
componentWillMount() {
this.props.loadInitialPosts();
}
renderItem({item}){
return <PostItem posts = { item } />;
}
renderInitialView(){
if(this.props.postDetailView === true){
return <PostDetail />;
}
else{
return <FlatList
data={this.props.posts}
renderItem={this.renderItem} />
}
}
render(){
return(<View style={styles.list}> {this.renderInitialView()} </View>);
}
}
/*
Avoid declaration of mapStateToProps object by defining this object
directly in the call to connect()
*/
export default connect((state => {
return {
posts : state.posts.map((val, id) => ({ ...val, id })),
postDetailView: state.postDetailView,
}
}), { loadInitialPosts })(PostsList)
I have initiated a state in _app.js using Next.js.
I would like to use this state in the index.js file.
How can I access it?
This is my _app.js code:
import React from 'react';
import App, { Container } from 'next/app';
import Layout from '../components/Layout';
export default class MyApp extends App {
constructor(props) {
super(props);
this.state = {
currencyType: {
name: 'Ether',
price: 1,
},
ethPriceUsd: 1,
};
}
static async getInitialProps({ Component, router, ctx }) {
let pageProps = {};
let ethPriceUsd;
if (Component.getInitialProps) {
fetch(`https://api.coingecko.com/api/v3/coins/ethereum/`)
.then((result) => result.json())
.then((data) => {
ethPriceUsd = parseFloat(data.market_data.current_price.usd).toFixed(
2
);
});
pageProps = await Component.getInitialProps(ctx);
}
return { pageProps, ethPriceUsd };
}
componentDidMount() {
const ethPriceUsd = this.props.ethPriceUsd;
this.setState({ ethPriceUsd });
}
onCurrencyTypeChange(currencyTypeValue) {
let currencyType = {};
//Value comes from Header.js where Ether is 0 and USD is 1
if (currencyTypeValue) {
currencyType = {
name: 'USD',
price: this.state.ethPriceUsd,
};
} else {
currencyType = {
name: 'Ether',
price: 1,
};
}
alert('We pass argument from Child to Parent: ' + currencyType.price);
this.setState({ currencyType });
}
render() {
const { Component, pageProps } = this.props;
return (
<Container>
<Layout changeCurrencyType={this.onCurrencyTypeChange.bind(this)}>
<Component {...pageProps} />
</Layout>
</Container>
);
}
}
A lot of it is irrelevant (Like passing the data to the Layout etc...). All I want to do is use this state in my index.js.
let's say you have this code in _app.js.
import React from 'react'
import App, { Container } from 'next/app'
export default class MyApp extends App {
static async getInitialProps({ Component, router, ctx }) {
let pageProps = {}
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return { pageProps }
}
state = {
name: "Morgan",
}
render () {
const { Component, pageProps } = this.props
return (
<Container>
<Component {...pageProps} {...this.state}/>
</Container>
)
}
}
Please notice the state and <Component {...pageProps} {...this.state}/>
Solution 1:
Now, let's see how can we use it in index.js or any other pages
import React from 'react';
export default class Index extends React.Component {
render() {
return (
<div>
<h2>My name is {this.props.name}</h2>
</div>
)
}
}
You can use them as props like this this.props.name
Solution 2:
Populate state in the index.js from props and then access it from state
import React from 'react';
export default class Index extends React.Component {
constructor(props) {
super(props)
this.state ={
name: this.props.name
}
}
render() {
return (
<div>
<h2>My name is {this.state.name}</h2>
</div>
)
}
}
You can use them as props like this this.state.name
I am serving some content from my API.
I want display response from API in my react component.
Response is html with bundled all assets inline by webpack.
How can I do it?
I tried dangerouslySetInnerHTML but it crashes my javascript inside returned html.
My cmp :
import React, { Component } from 'react';
import axios from 'axios';
export default class Report extends Component {
constructor() {
super();
this.state = {
id: null,
report: null
};
}
getParam(param){
return new URLSearchParams(window.location.search).get(param);
}
componentWillMount() {
axios.post(`/url`,
{
'id': this.getParam('id'),
}
)
.then(res => {
this.setState({id: res.data});
setTimeout(() => {
axios.get(`https://rg.ovh/`+this.state.id)
.then(res => {
this.setState({report: res.data})
});
}, 1900);
});
}
render() {
return (
<div dangerouslySetInnerHTML={ {__html: this.state.report} } />
);
}
}
import axios from 'axios';
import React, { Component } from 'react';
import renderHTML from 'react-render-html';
class App extends Component {
constructor() {
super();
this.state = {
htmlString: ''
};
}
componentDidMount() {
axios.get('http://localhost:5000').then(response => {
this.setState({ htmlString: response.data })
}).catch(err => {
console.warn(err);
});
}
render() {
const { htmlString } = this.state;
return (
<div className="App">
{renderHTML(htmlString)}
</div>
);
}
}
export default App;
I have got three components Topicscreen, Listview, Listrow. I am passing the function renderrow, and two other properties defined in my
Topicscreen to Listview.
Now when i call func in Listview, the props are passed to Listrow as defined in renderrow function, but the onRowclick function which is being passed to Listrow is undefined when i checked it in Listrow.
How to solve this error and pass onRowclick as a function to Listrow?
Topicscreen.js
class Topicscreen extends Component {
constructor() {
super();
this.onRowClick = this.onRowClick.bind(this);
}
componentDidMount() {
this.props.dispatch(topicaction.Fetchtopics());
}
renderLoading() {
return <p>Loading...</p>;
}
renderrow(rowid, topic) {
//const selected = this.props.checkselection[rowid]
const selected = "";
return (
<Listrow selected={selected} clicking={this.onRowClick} rowid={rowid}>
<h3>{topic.title}</h3>
<p>{topic.description}</p>
</Listrow>
);
}
onRowClick(rowid) {
this.props.dispatch(topicaction.selectedchoice(rowid));
}
render() {
if (!this.props.topicsByurl) return this.renderLoading();
return (
<div className="TopicsScreen">
Hi I am topic screen
<h1>Choose any three of the below topics</h1>
<Listview
rowid={this.props.topicsurlArray}
row={this.props.topicsByurl}
func={this.renderrow}
/>
</div>
);
}
}
Listview.js
import React, { Component } from "react";
import _ from "lodash";
export default class Listview extends Component {
constructor() {
super();
this.show = this.show.bind(this);
}
show(rowid) {
return this.props.func(rowid, _.get(this.props.row, rowid));
}
render() {
console.log("props in listview", this.props);
return (
<div>
<ul>{_.map(this.props.rowid, this.show)}</ul>
</div>
);
}
}
Listrow.js
import React, { Component } from "react";
export default class Listrow extends Component {
clicking() {
this.props.clicking(this.props.rowid);
}
render() {
console.log("list row called");
console.log("listrow props", this.props);
const background = this.props.selected ? "#c0f0ff" : "#fff";
return (
<div style={{ background }} onClick={this.clicking.bind(this)}>
{this.props.children}
</div>
);
}
}
You also need to bind your renderrow method in the Topicscreen constructor, or this.onRowClick inside of renderrow will not be what you expect.
class Topicscreen extends Component {
constructor(props) {
super(props);
this.onRowClick = this.onRowClick.bind(this);
this.renderrow = this.renderrow.bind(this);
}
// ...
}
Task is to fetch data from api when toggle between tags
When click on the link it calls the api service but state of feeds is not updated but it throws below warning
jQuery.Deferred exception: Cannot read property 'setState' of undefined TypeError: Cannot read property 'setState' of undefined
My github repo
https://github.com/dolphine4u/demo-app
APP component
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
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. 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:
addToFavorites = id => {
...
Same in ProductList component for the click handler:
onClick = () => {
this.props.update(this.props.id);
}