I'm finally not getting any errors, but now I can't get the data coming in from my database to render on the page
Here is the trouble component:
import React, { Component } from 'react';
import axios from 'axios';
export default class ListPets extends Component {
constructor(props) {
super(props);
this.state = {
pets: {},
isLoaded: false,
}
}
componentDidMount = () => {
This. getPets ();
};
getPets = async () => {
const res = await axios.get('http://localhost:5000/pets');
const pets = res.data;
this.setState({ isLoaded: true, pets });
console.log('Data has been received!');
}
render() {
console.log('State: ', this.state);
const { isLoaded, pets } = this.state;
if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<div>
<ul>
{Object.entries(pets).map(([key, pet]) => (
<li key={key}>{pet.name}</li>
))}
</ul>
</div>
);
}
}
}
Here is the data I'm trying to render from my database
{
"_id": "5dfe7b55a3678700785c9b69",
"species": "Collie",
"name": "Dax",
"age": "2",
"petImage": "C:\\fakepath\\brown-and-white-dog-4633734_640.jpg"
}
{
"_id": "5dfe828af33fa800ac8b49c8",
"species": "lab",
"name": "bea",
"age": "1",
"petImage": "C:\\fakepath\\puppy-1207816_640.jpg"
}
{
"_id": "5dfea025ea5cc2016e528f5a",
"species": "pittbull",
"name": "nina",
"age": "3",
"petImage": "C:\\fakepath\\pitbull1.jpg"
}
{
"_id": "5dfea0c229d0d4017b982f35",
"species": "pittbull",
"name": "nina",
"age": "3",
"petImage": "C:\\fakepath\\pitbull1.jpg"
}
{
"_id": "5dfea63eb1505e018a2ba363",
"species": "pittbull",
"name": "Gina",
"age": "3",
"petImage": "C:\\fakepath\\pitbull1.jpg"
}
{
"_id": "5dfea7a1fed64001b9632b8f",
"species": "pittbull",
"name": "kat",
"age": "2",
"petImage": "C:\\fakepath\\pitbull1.jpg"
}
If you are getting the data use the state
return (
<div>
<ul>
{this.state.pets.map(pet => (
<li key={pet.id}>{pet.name}</li>
))}
</ul>
</div>
);
}
}
}
Related
I am unable to setState in handleClick function for this App.
App is working very simple, it has a data that has an entry point in forest from there it just goes thru props till it gets to Tree component where divides to Children and Datum there it has a Collapsible that takes care of the expanding logic.
Now,
I just want to mutate state I have done many copies of that state with JSON.parse(JSON.Stringify())) used Lodash for deep copy, everything works expect that copied and mutated state just doesn't want to set into setState so I can't get it to circular working.
I just want to have a unidirectional data flow, but the 'setState' just doesn't work.
The function that mutates the state mutateState takes as arguments a forest a node.id a patch or get as a string value. I have tested it million times and it works, this function mutates the state via recursion. One thing maybe it has a problem that it doesn't return anything, even if it doesn't return it still doesn't want to set that 'setState'.
I have also used debugger million times and didn't find any clue. Please I need some help.
thank you.
import "./App.css";
import { useState, useEffect, useContext, createContext } from "react";
import React from "react";
import data from "./data.json";
import _ from "lodash";
function App() {
const [state, setState] = useState(data.data);
function mutateState(forest, nodeId, getOrPatch) {
let result;
forest.forEach(function (tree) {
if (tree.id === nodeId && getOrPatch === "patch") {
tree.toggle === true ? (tree.toggle = false) : (tree.toggle = true);
} else if (tree.id === nodeId && getOrPatch === "get") {
return (result = tree.toggle);
}
helper(tree);
});
function helper(tree) {
if (tree.children !== null) {
tree.children.forEach(function (tree) {
if (tree.id === nodeId && getOrPatch === "patch") {
tree.toggle === true ? (tree.toggle = false) : (tree.toggle = true);
} else if (tree.id === nodeId && getOrPatch === "get") {
return (result = tree.toggle);
}
helper(tree);
});
}
}
return result;
}
function Forest({ root }) {
return root.map((tree) => <Tree root={tree} key={tree.id} />);
}
function Tree({ root }) {
if (root.children !== null) {
return <Children key={root.id} node={root} />;
} else {
return <Datum key={root.id} node={root} />;
}
}
function Collapsible(props) {
return (
<ul>
<button onClick={props.handleClick} className="btn">
<li>{props.datum}</li>
</button>
{props.isExpanded ? props.children : ""}
</ul>
);
}
function Children({ node }) {
const [isExpanded, setIsExpanded] = useState(false);
let stateCopy = _.cloneDeep(state)
function handleClick() {
mutateState(stateCopy, node.id,'patch')
setState(stateCopy)
isExpanded ? setIsExpanded(false) : setIsExpanded(true);
}
return (
<Collapsible
datum={node.datum}
handleClick={handleClick}
isExpanded={isExpanded}
>
{node.children.map((tree) => (
<Tree key={tree.id} root={tree} />
))}
</Collapsible>
);
}
function Datum({ node }) {
return <li>{node.datum}</li>;
}
return (
<div className="App">
<header className="App-header">
<Forest root={state} />
</header>
</div>
);
}
export default App;
data JSON
{
"data": [
{
"datum": "String",
"id": 1,
"toggle": false,
"children": [
{
"datum": "String",
"id": 2,
"toggle": false,
"children": [
{
"datum": "String",
"id": 3,
"toggle": false,
"children": []
}
]
},
{
"datum": "String",
"id": 4,
"toggle": false,
"children": []
}
]
},
{
"datum": "String",
"id": 5,
"toggle": false,
"children": [{
"datum": "String",
"id": 6,
"children": []
}]
},
{
"datum": "String",
"id": 7,
"toggle": false,
"children": [
{
"datum": "String",
"id": 8,
"toggle": false,
"children": [
{
"datum": "String",
"id": 9,
"toggle": false,
"children": [
{
"datum": "String",
"id": 10,
"toggle": false,
"children": [
{
"datum": "String",
"id": 11,
"toggle": false,
"children": []
}
]
}
]
},
{
"datum": "String",
"id": 12,
"toggle": false,
"children": [
{
"datum": "String",
"id": 13,
"toggle": false,
"children": []
}
]
}
]
},
{
"datum": "String",
"id": 14,
"toggle": false,
"children": []
}
]
}
]
}
I am following a tutorial and when at this point I'm getting stuck. It gives me TypeError: Cannot read property 'filter' of undefined when I try to filter through the Product array. I was implementing the same functionality using Axios according to the tutorial and it was working. The instructor then changed to redux and I followed the same steps and that's when I got the error. I'm pretty new to React and completely new to Axios and Redux and I've been trying to find out what's wrong but I'm getting nowhere.
Here's my ProductScreens.jsx where the error occurs:
import React, { useEffect } from "react";
import Rating from "../Components/rating.jsx";
import { useDispatch, useSelector } from "react-redux";
import { listProducts } from "../actions/productActions.js"
function Sale({product}){
if("salePrice" in product){
return <li>Sale Price: ₹{product.salePrice}</li>;
}
else
return null;
}
export default function ProductsScreen(props){
const dispatch = useDispatch();
const productList = useSelector( state => state.productList);
const {loading,error,products} = productList;
useEffect(() =>{
dispatch(listProducts());
},[dispatch]);
const product = products.filter(prod => prod.category === props.match.params.category && prod.subcategory === props.match.params.subcategory);
return (
<div className="container-fluid main-cards">
<div className="row">
{
product.map(product => (
<div key={product._id} className="col-12 col-md-6 col-lg-4 main-card-item">
<div className="card">
</img>
<div className="card-body product-card list-group">
<h5 className="card-title">{product.name}</h5>
<p className="card-text">{product.description}</p>
<ul className="list-unstyled mt-3 mb-4">
<li>Price: ₹{product.price}</li>
<Sale product={product}/>
<li>Buy Now</li>
<li>
<Rating rating={product.rating} numReview={product.numReview}/>
</li>
</ul>
</div>
</div>
</div>
))};
</div>
</div>
)
}
Here is my productActions.js
import Axios from "axios";
import { PRODUCT_LIST_REQUEST, PRODUCT_LIST_SUCCESS, PRODUCT_LIST_FAIL } from "../constants/productConstants"
export const listProducts = () => async (dispatch) =>{
dispatch({
type: PRODUCT_LIST_REQUEST,
});
try {
const {data} = await Axios.get('/api/products');
dispatch({type: PRODUCT_LIST_SUCCESS, payload : data});
}catch(error){
dispatch({type: PRODUCT_LIST_FAIL, payload: error.message});
}
}
Here's my productReducers.js
export const productListReducer = (state = {loading: true, products: [] }, action) =>{
switch(action.type){
case PRODUCT_LIST_REQUEST :
return {loading: true};
case PRODUCT_LIST_SUCCESS:
return {loading: false, products: action.payload};
case PRODUCT_LIST_FAIL :
return {loading: false, error: action.payload};
default:
return state;
}
}
And my productConstants.js
export const PRODUCT_LIST_REQUEST = "PRODUCT_LIST_REQUEST";
export const PRODUCT_LIST_SUCCESS = "PRODUCT_LIST_SUCCESS";
export const PRODUCT_LIST_FAIL = "PRODUCT_LIST_FAIL";
I've tried solving it but I can't find out what's wrong. I did console.log(products) instead of const product = products.filter(prod => prod.category === props.match.params.category && prod.subcategory === props.match.params.subcategory); in ProductScreens.jsx and also replaced the contents of return with <h1></h1> and got back the following object:
[
{
"_id": "1",
"name": "example1",
"category": "example category1",
"subcategory": "example subcategory1",
"image": [
{
"_id": "image1",
"name": "/images/example1.jpg"
}
],
"mainImage": "/images/example1.jpg",
"price": "19000",
"brand": "brand1",
"rating": 4.5,
"numReview": 10,
"description": "some description for example1."
},
{
"_id": "2",
"name": "example2",
"category": "example category1",
"subcategory": "example subcategory1",
"image": [
{
"_id": "image2",
"name": "/images/example2.jpg"
}
],
"mainImage": "/images/example2.jpg",
"price": "16791",
"salePrice": "15500",
"brand": "brand2",
"rating": 4.7,
"numReview": 10,
"description": "some description for example2."
},
{
"_id": "3",
"name": "example",
"category": "example category2",
"subcategory": "example subcategory3",
"image": [
{
"_id": "image3",
"name": "/images/example3-1.jpg"
},
{
"_id": "image4",
"name": "/images/example3-2.jpg"
},
{
"_id": "image5",
"name": "/images/example3-3.jpg"
},
{
"_id": "image6",
"name": "/images/example3-4.jpg"
}
],
"mainImage": "/images/example3-1.jpg",
"price": "8549",
"salePrice": "7200",
"brand": "brand3",
"rating": 3,
"numReview": 10,
"description": "some description for example3."
},
{
"_id": "4",
"name": "example4",
"category": "example category3",
"subcategory": "example subcategory4",
"image": [
{
"_id": "image7",
"name": "/images/example4.jpg"
}
],
"mainImage": "/images/example4.jpg",
"price": "450",
"brand": "brand4",
"rating": 4.5,
"numReview": 10,
"description": "some description for example4."
},
{
"_id": "5",
"name": "example5",
"category": "example category1",
"subcategory": "example subcategory2",
"image": [
{
"_id": "image8",
"name": "/images/example5.jpg"
}
],
"mainImage": "/images/example5.jpg",
"price": "30000",
"salePrice": "27000",
"brand": "brand5",
"rating": 4.5,
"numReview": 10,
"description": "some description for example5"
}
]
Looking at the object above, filter() should work but it's not. Moreover, the above object was the same object I got when I used axios and it worked fine then. So I have no idea why it's not working anymore.
Also when I try to console.log(products._id) or any other property, I get the same TypeError. I tried console.log(products[0]) thinking maybe I have to do that to get the first object since its an array of objects, I got TypeError: Cannot read property '0' of undefined.
So I figured it out. I found two solutions. First, Turns out I was getting two objects before the PRODUCT_LIST_SUCCESS action occured. In the first object, the products was an empty array from the initial state and in the second object which was receieved from PRODUCT_LIST_REQUEST action, there was only a loading property so products was undefined. So I changed the switch case statement in productsReducers.js for PRODUCT_LIST_REQUEST to return {loading: true, products: []}; and that did the trick.
My second solution is to check if loading is true or false and only execute my code and render the page if loading is false.
I haven't been an avid programmer so I don't know best programming practices but I'm using the second solution.
there I am studying to fetch data from firebase realtime database I watched various youtube videos and few posts and got this far code is kinda right and don't know where I made a mistake I would be happy if someone helps me I have attached both JSON and react code for better understanding. I was only able to fetch IDs only from the database ...
here is code
import React, { Component, Fragment } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import firebase from './firebase.js';
class App extends Component {
constructor(props) {
super(props);
this.state = {
accounts: [],
users: [],
}
}
componentDidMount() {
const accountRef = firebase.database().ref('accounts');
accountRef.on('value', (snapshot) => {
let accounts = snapshot.val();
let newState = [];
for (let account in accounts) {
newState.push({
id:account,
account: accounts[account].account,
title: accounts[account].title,
})
}
this.setState({
accounts:newState,
})
})
const userRef = firebase.database().ref('users');
userRef.on('value', (snapshot) => {
let users = snapshot.val();
let newUserState = [];
for (let data in users) {
newUserState.push({
id:data,
account:users[data].account,
name: users[data].name,
})
console.log(data)
}
})
}
render() {
return (
<Fragment >
<section>
<div>
<h2>User Details</h2>
{this.state.accounts.map( data =>
<div key={data.id}>
{console.log(data.title)}
<h4 >{data.account}</h4>
<h4 >{data.name}</h4>
</div>
)}
</div>
<div>
<h2>User Apps</h2>
{this.state.accounts.map( accounts =>
<div key={accounts.id}>
{/* {console.log(accounts.title)} */}
<h4 >{accounts.id}</h4>
<h4 >{accounts.title}</h4>
</div>
)}
</div>
</section>
</Fragment>
);
}
}
export default App;
here is josn file structure
{
"accounts": {
"-Kd_teAAXcw2b5MyFPIT": {
"apps": {
"cuckoosnest": {
"title": "One Flew Over The Cuckoo’s Nest"
}
}
},
"-Kd_ZCjRYSGzISxY_5Wi": {
"apps": {
"psycho": {
"title": "Psycho"
}
}
},
"-Kda3ClE2i0vZzyh7uh0": {
"apps": {
"addams": {
"title": "The Addams Family"
}
}
},
"-Kda8nknT6-XyJE_SjCl": {
"apps": {
"princess-bride": {
"title": "The Princess Bride"
}
}
},
"-KdeN0Yk89J4l5hMJ6Ea": {
"apps": {
"mi": {
"title": "Mission: Impossible"
}
}
},
"-KdWbLKO0uZ0W5LYe9gj": {
"apps": {
"bladerunner": {
"title": "Blade Runner"
}
}
},
"-KdWI6HAF0_wh9-NTEpe": {
"apps": {
"dragontattoo": {
"title": "The Girl With The Dragon Tattoo"
}
}
},
"-KdWPnObbAbjd9lHX___": {
"apps": {
"nakedgun": {
"title": "Naked Gun"
}
}
},
"-Ke4dwlXoIBXPgB8v9Pt": {
"apps": {
"scarface": {
"title": "Scarface"
}
}
},
"-Ke4YQMM3aTQ-u19uIuv": {
"apps": {
"fargo": {
"title": "Fargo"
}
}
}
},
"users": {
"00L91c7cvUaghNmGlC0lJa9eZ102": {
"account": "-Kd_teAAXcw2b5MyFPIT",
"name": "Randle McMurphy"
},
"0YRaZC6EUrc5sc8Ab4AR7Zp7ig93": {
"account": "-Kd_ZCjRYSGzISxY_5Wi",
"name": "Norman Bates"
},
"11yVrZ6TK3ZuKpITF8UVGF4ILlC3": {
"name": "Wednesday Addams",
"account": "-Kda3ClE2i0vZzyh7uh0"
},
"2d0WRN7v3lYNc9DX02yMfLmTiIM2": {
"name": "Inigo Montoya",
"account": "-Kda8nknT6-XyJE_SjCl"
},
"39IY5AX8zfgtztbQ4RFCJ0dSsel1": {
"name": "Ethan Hunt",
"account": "-KdeN0Yk89J4l5hMJ6Ea"
},
"39VBFQdD1qNgNydJ2A6kdoVLhIc2": {
"name": "Roy Batty",
"account": "-KdWbLKO0uZ0W5LYe9gj"
},
"3ACrWNFyEVObZaWMcMmZq9C045h1": {
"name": "Lisbeth Salander",
"account": "-KdWI6HAF0_wh9-NTEpe"
},
"3C9RrP8bxAVRhRcPHNBOpc5oTo83": {
"name": "Frank Drebin",
"account": "-KdWPnObbAbjd9lHX___"
},
"3kqJLMDHO2N5APYHpv5H8VtRXoj1": {
"name": "Tony Montana",
"account": "-Ke4dwlXoIBXPgB8v9Pt"
},
"44w3em7XKfhKcSSvQVk8hJIfsBQ2": {
"name": "Marge Gunderson",
"account": "-Ke4YQMM3aTQ-u19uIuv"
}
}
}
To fix the users data you need to do this
const userRef = firebase.database().ref('users');
userRef.on('value', (snapshot) => {
let newUserState = [];
snapshot.forEach(data => {
const dataVal = data.val()
newUsersState.push({
id: data.key,
name: dataVal.name,
account: dataVal.account
})
})
})
for the accounts data i am not sure what information you are trying to add to the state.... you are trying to call .account & .title but that does not exist in the snapshot.. but either way your data is poorly structured and makes it difficult to manage
I receive JSON from my back end, I save it in my state and I want to use it in props in another react component, but it doesn't work.
I try to show need date like that in props of my component - {this.state.movies["0"]["title"]}, but it doesn't work.
constructor() {
super();
this.state = {
movies: []
}
}
componentDidMount() {
this.getAllMoviesForMainPage();
}
getAllMoviesForMainPage() {
axios.get("http://localhost:8080/showAll")
.then(response => {
this.setState({ movies: response.data })
})
}
render() {
return (
<div className="qwerty">
<MainPageComponent />
<div className='moviePreviewGrid'>
<Router>
<div className="moviePreviewGrid-row">
<div className="moviePreviewGrid-col">
<MoviePreview
Title={this.state.movies["2"]["title"]}
MoviePreviewAvatar={DrivePoster}
SeeMore="unrelated long string here"
/>
<NavLink to="/showByTitle/Драйв">
<button type="button" className="myBtn">See more</button>
</NavLink>
</div>
and structure of my JSON
[
{
"id": 1,
"title": "Джокер",
"releaseDate": "2019",
"genre": "Триллер, драма, криминал",
"duration": "122 минуты",
"rating": 8.7,
"criticReviews": [
{
"criticName": "Anton",
"review": "anton review"
},
{
"criticName": "OldCritic",
"review": "old review"
}
],
"userReviews": [
{
"nickName": "Igor",
"review": "igor review"
},
{
"nickName": "Nik",
"review": "nik review"
}
]
},
{
"id": 2,
"title": "Ирландец",
"releaseDate": "2019",
"genre": "Драма, триллер, криминал, биографический",
"duration": "209 минут",
"rating": 8.4,
"criticReviews": [
{
"criticName": "YoungCritic",
"review": "young review"
}
],
"userReviews": [
{
"nickName": "Gambit",
"review": "gambit review"
},
{
"nickName": "Andrew",
"review": "andrew review"
}
]
},
{
"id": 3,
"title": "Драйв",
"releaseDate": "2011",
"genre": "Боевик, драма",
"duration": "100 минут",
"rating": 7.8,
"criticReviews": [
{
"criticName": "Critic",
"review": "review"
}
],
"userReviews": [
{
"nickName": "Anton",
"review": "anton review"
}
]
},
{
"id": 4,
"title": "Последний человек на Земле",
"releaseDate": "2015",
"genre": "Комедия",
"duration": "22 минуты",
"rating": 7.3,
"criticReviews": [
{
"criticName": "NewCritic",
"review": "new review"
}
],
"userReviews": [
{
"nickName": "Atomf7",
"review": "atomf7 review"
}
]
},
{
"id": 5,
"title": "Интерстеллар",
"releaseDate": "2014",
"genre": "Фантастика, драма, приключения",
"duration": "169 минут",
"rating": 8.6,
"criticReviews": [
{
"criticName": "Nik",
"review": "nik review"
}
],
"userReviews": [
{
"nickName": "Alice",
"review": "alice review"
}
]
}
]
and i wont to have for example title of first movie
In the first init, the this.state.movies has a length of 0 so this.state.movies["2"]["title"] of course would have no value at all
because getAllMoviesForMainPage is async (axios call) and takes a little longer to complete, so first you must give it an initial value and only when the request completes you can give it the real value.
example:
<MoviePreview
Title={this.state.movies.length > 0 ? this.state.movies[2].title : ""}
MoviePreviewAvatar={DrivePoster}
/>
Usually a state, isLoading is used for this case. So you can know when you received your data.
In the first render movies are not already fetched from the api.
So you need to conditionally render it.
import React, { Component } from "react";
import axios from "axios";
export default class Test extends Component {
constructor() {
super();
this.state = {
movies: [],
loading: true
}
}
componentDidMount() {
this.getAllMoviesForMainPage();
}
getAllMoviesForMainPage() {
axios.get("http://localhost:8080/showAll")
.then(response => {
this.setState({ movies: response.data, loading: false })
})
}
render() {
const { loading, movies } = this.state;
if (loading) {
return <div>Loading...</div>;
} else {
return (
<div>
{movies.length > 0 ? (
<div>First movie title: {movies[0].title}</div>
) : (
<div>No movies</div>
)}
</div>
);
}
}
}
You can check this example using a fake api.
You are making a GET request in componentDidMount which is async so until the promise is resolve in .then(.. your state does not contain response.data in movies.
The important thing to remember is component gets re-render every time you do this.setState(.. , so before you do setState in your getAllMoviesForMainPage method, the initial render will happen and it will contain an empty array in this.state.movies that you have defined in constructor
Also since your response contains array of objects, you would be using movies['2'].title instead of movies['2']['title']
So your render method should contain something like this to show movie preview:
<div className="moviePreviewGrid-col">
{this.state.movies.length ? (
<MoviePreview
Title={this.state.movies['2'].title}
MoviePreviewAvatar={DrivePoster}
SeeMore="unrelated long string here"
/>
) : (
<PlaceHolderPreview />
)}
<NavLink to="/showByTitle/Драйв">
<button type="button" className="myBtn">
See more
</button>
</NavLink>
</div>
PlaceHolderPreview can be your another component that will show -- well a placeholder for preview.
Hope it all makes sense.
I am trying to get and show a specific data from api in a <Text> tag in my React Native app.
What I'm trying to do is to show the name of second object from that api.
Here is my code :
class HomeSreen extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: [],
};
}
componentDidMount() {
const request = new Request('http://jsonplaceholder.typicode.com/users');
fetch(request)
.then(response => response.json())
.then(responseJson => {
this.setState({
dataSource: responseJson,
});
});
}
render() {
return (
<View>
<Text>Home Screen</Text>
<Text>{this.state.dataSource[1].name}</Text>
</View>
);
}
}
And the API :
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere#april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"email": "Shanna#melissa.tv",
"address": {
"street": "Victor Plains",
"suite": "Suite 879",
"city": "Wisokyburgh",
"zipcode": "90566-7771",
"geo": {
"lat": "-43.9509",
"lng": "-34.4618"
}
},
"phone": "010-692-6593 x09125",
"website": "anastasia.net",
"company": {
"name": "Deckow-Crist",
"catchPhrase": "Proactive didactic contingency",
"bs": "synergize scalable supply-chains"
}
},
.
.
.
But I can't get the data I need.
Any help would be appreciated
these data requests asynchronously, so when the first render occurs, there is no data returned from the API.
class HomeSreen extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: [],
};
}
componentDidMount() {
const request = new Request('http://jsonplaceholder.typicode.com/users');
fetch(request)
.then(response => response.json())
.then(responseJson => {
this.setState({
dataSource: responseJson,
});
});
}
render() {
return (
<View>
<Text>Home Screen</Text>
{
this.state.dataSource.length === 0 ?
<Text>Waiting moment.</Text> :
<Text>{this.state.dataSource[1].name}</Text>
}
</View>
);
}
}
Making these changes you can visualize the data you need.
If the problem is that your component isn't updating the that property after the request is complete it is because you are doing a 'shallow merge' on the dataSource Array so React isn't able to detect changes to the data. There are a few ways you can handle it:
Deep merge
fetch(request)
.then(response => response.json())
.then(responseJson => {
this.setState(prevState => {
return {
...prevState.dataSource,
dataSource: responseJson.map((obj, i)=>{ return {...dataSource[i], ...obj}},
}
});
});
https://reactjs.org/docs/optimizing-performance.html#shouldcomponentupdate-in-action
Pull the name property out to the top-level of you component state
class HomeSreen extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: [],
screenTitle
};
}
componentDidMount() {
const request = new Request('http://jsonplaceholder.typicode.com/users');
fetch(request)
.then(response => response.json())
.then(responseJson => {
this.setState({
screenTitle: responseJson[1].name,
});
});
}
render() {
return (
<View>
<Text>Home Screen</Text>
<Text>{this.state.screenTitle}</Text>
</View>
);
}
}