Pass state from one component to another in ReactJs - javascript

I am building a Weather Application, and I need to seperate the Weather card into its own component. So far, while I had the Weather card in my Weather.js file it has been working good. But now I have seperated the Weather card into its own component but I cannot access the state.
This is my main component where I have my state:
export default class Weather extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
items: [],
selectedValue: ''
};
}
componentDidMount() {
fetch("http://api.weatherapi.com/v1/forecast.json?key=ca021cd2c43544e0be7112719202206&q=kosovo&days=3")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
items: result
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
);
}
render() {
const { error, isLoaded, items } = this.state;
return (
<WeatherCard items={this.state}/>
)
}
}
This is the other component that I am trying to use the state
const WeatherCard = (props) => {
return (
<div>
<h2>Today</h2>
<span>{this.props.items.location.country}</span>
</div>
)
}
The error that I get is: undefined has no properties

render() {
const { error, isLoaded, items } = this.state;
return (
<WeatherCard items={items}/>
)
}
And in your weather component
const WeatherCard = (props) => {
return (
<div>
<h2>Today</h2>
<span>{props.items.location.country}</span>
</div>
)

render() {
const { error, isLoaded, items } = this.state;
return (
<WeatherCard items={this.state}/>
)
}
change to
render() {
const { error, isLoaded, items } = this.state;
return (
<WeatherCard items={items}/>
)
}
and
const WeatherCard = (props) => {
return (
<div>
<h2>Today</h2>
<span>{this.props.items.location.country}</span>
</div>
)
}
change to this
const WeatherCard = (props) => {
return (
<div>
<h2>Today</h2>
<span>{props.items.location.country}</span>
</div>
)
}

Related

Not getting data from api into the web page, can anyone help me through this where I am getting an error and what can i do to get data

import React from 'react';
/**
App
Simple react js fetch example
*/
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [],
isLoaded: false
}
}
/**
componentDidMount
Fetch json array of objects from given url and update state.
*/
componentDidMount() {
fetch('https://run.mocky.io/v3/8260aa5d-8af8-4cff-999e-6e81b217f0ba')
.then(res => res.json())
.then(json => {
this.setState({
items: json,
isLoaded: true,
})
}).catch((err) => {
console.log(err);
});
}
/**
render
Render UI
*/
render() {
const { isLoaded, items } = this.state;
if (!isLoaded)
return Loading...;
return (
{items.map(item => (
Name: {item.name}
))}
);
}
}
export default App;
in render function
return (
{
items.clients.map(item => (<span key={item.id}> Name : {item.name}
</span>)
)
}
)

TypeError: this.state.data.map in reactjs

class Home extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoaded: false,
};
}
componentDidMount() {
fetch("https://reqres.in/api/users?page=2")
.then((res) => res.json())
.then((json) => {
this.setState({
isLoaded: true,
data: json,
});
});
}
render() {
var { isLoaded, data }= this.state;
if(!isLoaded){
return<div>Is isLoaded</div>
}
else{
return (
<div>
<ul>
{() =>
this.state.data.map((data, index) => (
<li key={index}>Email: {data.email}</li>
))
}
;
</ul>
</div>
);
}
}
}
export default Home;
Hii All , I know this question is asked many times but I cant figure it out I'am getting the error. I have checked for all the questions similar to this but haven't found specific solution if I use another link i.e, "https://jsonplaceholder.typicode.com/users" this one the code works fine .
The returned data from https://reqres.in/api/users?page=2 is not an array, but an object with a data property containing what you are looking for (an array). The result of the request is :
{"page":1,"per_page":6,"total":12,"total_pages":2,"data":[{"id":1,"email":"george.bluth#reqres.in","first_name":"George","last_name":"Bluth","avatar":"https://reqres.in/img/faces/1-image.jpg"},{"id":2,"email":"janet.weaver#reqres.in","first_name":"Janet","last_name":"Weaver","avatar":"https://reqres.in/img/faces/2-image.jpg"},{"id":3,"email":"emma.wong#reqres.in","first_name":"Emma","last_name":"Wong","avatar":"https://reqres.in/img/faces/3-image.jpg"},{"id":4,"email":"eve.holt#reqres.in","first_name":"Eve","last_name":"Holt","avatar":"https://reqres.in/img/faces/4-image.jpg"},{"id":5,"email":"charles.morris#reqres.in","first_name":"Charles","last_name":"Morris","avatar":"https://reqres.in/img/faces/5-image.jpg"},{"id":6,"email":"tracey.ramos#reqres.in","first_name":"Tracey","last_name":"Ramos","avatar":"https://reqres.in/img/faces/6-image.jpg"}],"support":{"url":"https://reqres.in/#support-heading","text":"To keep ReqRes free, contributions towards server costs are appreciated!"}}
So you cannot use map function, which is from the Array prototype, on the result of your request. You must access the data property first :
this.state.data.data.map((data, index) => ( // note the double data
<li key={index}>Email: {data.email}</li>
))
You could also assign json.data to the state.data to avoid the ugly .data.data :
this.setState({
isLoaded: true,
data: json.data, // note the .data
});
I think the problem is in brackets around your .map() method. Please try this
class Home extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoaded: false,
};
}
componentDidMount() {
fetch("https://reqres.in/api/users?page=2")
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
data: json,
});
});
}
render() {
const { isLoaded, data } = this.state;
if (!isLoaded) {
return <div>Is isLoaded</div>;
} else {
return (
<div>
<ul>
{data?.map((data, index) => {
return <li key={index}>Email: {data.email}</li>;
})}
</ul>
</div>
);
}
}
}
export default Home;
I don't see any error, it's working just fine.
Output:
Working Example: StackBlitz
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoaded: false,
};
}
componentDidMount() {
fetch('https://reqres.in/api/users?page=2')
.then((res) => res.json())
.then((json) => {
console.log(json.data);
this.setState({
isLoaded: true,
data: json.data,
email: null,
});
});
}
render() {
var { isLoaded, data } = this.state;
if (!isLoaded) {
return <div>Is isLoaded</div>;
} else {
return (
<div>
<div className="contents home">
<img
src="https://trucard.io/india/wp-content/uploads/2021/08/2021-June-TruCard-Logo.png
"
width={50}
alt="img"
className="trucard-img"
/>
</div>
<div className="button">
<button className="button-button">Load list</button>
</div>
<ul>
{this.state.data?.map((data, index) => (
<li key={index}>Email: {data.email}</li>
))}
;
</ul>
</div>
);
}
}
}
export default App;

Accessing an element inside an array with multiple objects

I'm trying to use an api with football teams, I want to simply render the name of the teams in a div or a list. But it just render the last one.
When I console.log it, it shows all the teams
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
teams: [],
isLoaded: false
}
}
componentDidMount() {
fetch('https://www.thesportsdb.com/api/v1/json/1/search_all_teams.php?l=English%20Premier%20League')
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
data: json,
})
})
}
render() {
var {
isLoaded,
data
} = this.state;
if (!isLoaded) {
return <div> Loading... < /div>
} else {
for (var key in data.teams) {
if (data.teams.hasOwnProperty(key))
console.log(data.teams[key].strTeam)
}
return ( <div className = "App" >
Premier League Teams!{
data.teams[key].strTeam
} </div>
);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Try this:
return (
<div className="App">
Premier League Teams!{data.teams.map(team => team.strTeam)}
</div>
);
This will loop through the teams array with map and render each one.
Try this,
import React from "react";
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
teams: [],
isLoaded: false
};
}
componentDidMount() {
fetch(
"https://www.thesportsdb.com/api/v1/json/1/search_all_teams.php?l=English%20Premier%20League"
)
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
data: json
});
});
}
render() {
var { isLoaded, data } = this.state;
if (!isLoaded) {
return <div>Loading... </div>;
} else {
return (
<div className="App">
Premier League Teams!
{data.teams.map(team => (
<div> {team.strTeam} </div>
))}
</div>
);
}
}
}
export default Test;

React Expected an assignment or function call and instead saw an expression

I'm trying to render the data from my database get this instead Failed to compile.
./src/components/list-pets.component.js
Line 38:5: Expected an assignment or function call and instead saw an expression no-unused-expressions
Search for the keywords to learn more about each error.enter code here
Here is my code from 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: []
};
}
componentDidMount = () => {
this.getPets();
};
getPets = () => {
axios.get('http://localhost:5000/pets')
.then((response) => {
const data = response.data;
this.setState({ pets: data });
console.log('Data has been received!');
})
.catch((err) => {
console.log(err);
});
}
displayPet = (pets) => {
if (!pets.length) return null;
return pets.map((pet, index) => {
<div key={index}>
<h3>{pet.name}</h3>
<p>{pet.species}</p>
</div>
});
};
render() {
console.log('State: ', this.state);
return (
<div className='adopt'>
{this.displayPet(this.state.pets)}
</div>
)
}
}
You need to return a value at each pets.map iteration, currently you’re returning undefined.
return pets.map((pet, index) => {
return (
<div key={index}>
<h3>{pet.name}</h3>
<p>{pet.species}</p>
</div>
)
});
You have to wait until fetching data is completed.
You should have to define the loading bar while fetching.
class App extends Component {
constructor() {
super();
this.state = {
pageData: {},
loading: true
}
this.getData();
}
async getData(){
const res = await fetch('/pageData.json');
const data = await res.json();
return this.setState({
pageData: data,
loading: false
});
}
componentDidMount() {
this.getData();
}
render() {
const { loading, pageData } = this.state;
if (loading){
return <LoadingBar />
}
return (
<div className="App">
<Navbar />
</div>
);
}
}

Issue with react onClick

My app has an onClick that should be rendering more gifs. However, it does it once and then stops. Also, the onClick deletes all the gifs that were already on the page. Anyone know what I'm doing wrong?
class App extends Component {
constructor(props) {
super(props);
this.state = {
results: [],
};
}
componentDidMount() {
this.searchGifs('kittens');
}
searchGifs = (searchQuery) => {
fetch(`http://api.giphy.com/v1/gifs/search?q=${searchQuery}&limit=12&api_key=dc6zaTOxFJmzC`).then(data => data.json())
.then(response => {
this.setState({
results: response.data,
});
});
}
searchMoreGifs = (offsetQuery) => {
fetch(`http://api.giphy.com/v1/gifs/search?q=${offsetQuery}&limit=12&offset=${this.state.results.length}&api_key=dc6zaTOxFJmzC`).then(data => data.json())
.then(response => {
this.setState({
results: response.data,
});
});
}
render() {
return (
<main className="app">
<Header />
<SearchForm startSearch={this.searchGifs} />
<ResultList gifs={this.state.results} />
<LoadMore gifs={this.state.results} searchMore={this.searchMoreGifs} />
</main>
);
}
}
and here is the onClick:
class LoadMore extends React.Component {
render(props) {
return(
<button onClick={this.props.searchMore}>Load More</button>
);
}
}
export default LoadMore;
Each time you call this.setState({results: something}) you completely overwrite the previous state of results.You want to take the array that is in this.state.results and concat it with the new results.
class App extends Component {
constructor(props) {
super(props);
this.state = {
results: [],
// I also suggest moving the searchQuery to the state so it can be used in both the offset and the original search
searchQuery: 'kittens'
};
}
componentDidMount() {
this.searchGifs(this.state.searchQuery);
}
searchGifs = (searchQuery) => {
fetch(`http://api.giphy.com/v1/gifs/search?q=${searchQuery}&limit=12&api_key=dc6zaTOxFJmzC`).then(data => data.json())
.then(response => {
this.setState({
results: response.data,
});
});
}
searchMoreGifs = (offsetQuery) => {
fetch(`http://api.giphy.com/v1/gifs/search?q=${offsetQuery}&limit=12&offset=${this.state.results.length}&api_key=dc6zaTOxFJmzC`).then(data => data.json())
.then(response => {
this.setState({
// You were overwriting the old results with new data every time you ran this function
results: this.state.results.concat(response.data),
});
});
}
render() {
return (
<main className="app">
<Header />
<SearchForm startSearch={this.searchGifs} />
<ResultList gifs={this.state.results} />
{/* You also need to pass the offsetQuery to the LoadMore component so that the searchMore function can use it*/}
<LoadMore searchMore={this.searchMoreGifs} offsetQuery={this.state.searchQuery} />
</main>
);
}
}
class LoadMore extends React.Component {
render(props) {
const {offsetQuery, searchMore} = this.props
return (
<button onClick={() => searchMore(offsetQuery)}>Load More</button>
);
}
}
export default LoadMore;

Categories

Resources