How to pass state within state in react native - reactjs

I want to pass my data array and favorites array which both I am setting in states. I want to pass my favorites array state in my data state. How can I achieve that?? My code looks like this
class Favorites extends Component {
constructor(props) {
super(props);
this.state = {
favorites: [],
data: [],
};
}
axios
.post(
'http://staging.islamicmedia.com.au/wp-json/islamic-media/v1/user/media/library',
data,
)
.then((res) => {
console.log(res.data);
this.setState({
data: res.data,
favorites: res.data.data.favorite.filter((val) => val != null),
});
});
};

You should do that axios call in the componentDidMount:
class Favorites extends Component {
constructor(props) {
super(props);
this.state = {
favorites: [],
data: [],
};
}
componentDidMount() {
axios
.post(
'http://staging.islamicmedia.com.au/wp-json/islamic-media/v1/user/media/library',
data,
)
.then((res) => {
const favs = res.data.data.favorite.filter((val) => val !== null);
this.setState({
data: res.data,
favorites: favs
});
});
};
}

Related

react setState function is not workin

I am new at react and
I have been trying to apply event handling in react but facing some Problem on onclick event.
When the button "show me of germany" is called the Page then stuck to loading only ...
Here is the code i have written ..
class App extends Component {
constructor(props) {
super(props);
this.state = { articles: [],
isLoaded:false ,
country:'us'
}
this.change = this.change.bind(this);
}
componentDidMount() {
const APIurl = `https://newsapi.org/v2/top-headlines?country=${this.state.country}&apiKey=${API_KEY}`;
fetch(APIurl)
.then(response => response.json())
.then(json => {
this.setState({
articles: json.articles,
isLoaded:true
})
})
}
// function to change the state
change()
{
this.setState({
articles: [],
isLoaded:false ,
country:"de"
})
}
render() {
const { isLoaded,articles } = this.state;
if(!isLoaded)
{
return (<h1>Loading....</h1>)
}
return (
<div>
<Navbar/>
<button onClick={this.change}>show me of germany</button>
<ul>
{articles.map(item=>(
<News item={item}/>
))}
</ul>
</div>
);
}
}
export default App;
Hope you understood the problem
You have to do request again.
class App extends Component {
constructor(props) {
super(props);
this.state = {
articles: [],
isLoaded: false,
country:'us'
}
this.change = this.change.bind(this);
}
componentDidMount() {
fetchData(this.state.country);
}
componentDidUpdate(prevProps, prevState) {
const { country: prevCountry } = prevState;
const { country: nextCountry } = this.state;
if (prevCountry !== nextCountry) {
fetchData(nextCountry);
}
}
change() {
this.setState({ country: 'de' });
}
fetchData(country) {
this.setState({ articles: [], isLoaded: false });
fetch(
`https://newsapi.org/v2/top-headlines?country=${country}&apiKey=${API_KEY}`
)
.then(res => res.json())
.then(({ articles }) => {
this.setState({ articles, isLoaded: true });
})
.catch(console.error);
}
render() {
//...
}
}
export default App;

How to get state which comes from props which is got from API in React

What I want to do
When a child component first rendering, I would like to use the value in props from a parent component
Problem
When a child component is first rendered, props is not set to state in the child component
I am a beginner to React. I am trying to use props in order to call API by axios in componentDidMount in a child component. I mean, what I am doing is calling API in a parent component and setting data from this API to a child component as props.
However, when I try to do that, props is not set to state in a child component.
For example, when I retrieve product which has some category, I type localhost:3000/api/parent/?category=1/. But, my console.log shows me localhost:3000/api/parent/?category=undefined because I guess props is not set when a child component first rendering.
Actually, I can see category object in state like below.
I guess props is completely set to state after the child component finish first rendering.
How could I set props which comes from API to state?
Although I tried many solutions I found on the stackoverflow, I got stuck at this problem so long time.
I would like you to tell me some solutions.
Thank you very much.
== == ==
My code is like this.
Parent Component
class Top extends Component {
constructor(props) {
super(props);
this.state = {
loginUser: '',
categories: [],
};
}
async componentDidMount() {
const localhostUrl = 'http://localhost:8000/api/';
const topCategoryList = ['Smartphone', 'Tablet', 'Laptop'];
let passCategoryToState=[]
axios
.get(localhostUrl + 'user/' + localStorage.getItem('uid'))
.then((res) => {
this.setState({ loginUser: res.data });
})
.catch((err) => console.log(err));
await Promise.all(
topCategoryList.map(async (category) => {
await axios.get(localhostUrl + 'category/?name=' + category).then((res) => {
passCategoryToState=[...passCategoryToState, res.data]
console.log(passCategoryToState);
});
})
);
this.setState({categories : passCategoryToState})
}
render() {
if (!this.props.isAuthenticated) {
return <p> Developing now </p>;
}
if (this.state.loginUser === '' ) {
return <CircularProgress />;
} else {
return (
<>
<Header loginUser={this.state.loginUser} />
<Give_Item_List
axiosUrl="http://localhost:8000/api/"
subtitle="Smartphone Items"
loginUser={this.state.loginUser}
category={this.state.categories[0]}
/>
</>
);
}
}
}
export default Top;
And, child component
class Give_Item_List extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
loginUser: this.props.loginUser,
category: this.props.category,
};
}
async componentDidMount() {
let pickedGiveItems;
await this.setState({ loading: true });
await axios
.get(this.props.axiosUrl + 'giveitem/?category=' + this.state.category.id)
.then((res) => {
pickedGiveItems = res.data;
console.log(pickedGiveItems);
})
.catch((err) => console.log('Not found related to Items'));
this.setState({ loading: false });
}
render() {
if (this.state.loading == true) {
return <CircularProgress />;
}
return <h1>Give_Item_List</h1>;
}
}
export default Give_Item_List;
==============
Edit:Change to componentDidUpdate
componentDidUpdate(prevProps) {
if(prevProps.category != this.props.category){
let pickedGiveItems;
this.setState({ loading: true });
axios
.get(this.props.axiosUrl + 'giveitem/?category=' + this.props.category.id)
.then((res) => {
pickedGiveItems = res.data;
console.log(pickedGiveItems);
})
.catch((err) => console.log('NotFount'));
this.setState({ loading: false });
}
}
It still doesn't work...
In the constructor, this.props is undefined, but you can access the props directly.
constructor(props) {
super(props);
this.state = {
loading: false,
loginUser: props.loginUser,
category: props.category,
};
}
However, I should note now that storing props in state is a common react anti-pattern, you should always consume prop values from this.props where you need them.
For example:
async componentDidMount() {
let pickedGiveItems;
await this.setState({ loading: true });
await axios
.get(this.props.axiosUrl + 'giveitem/?category=' + this.props.category.id)
.then((res) => {
pickedGiveItems = res.data;
console.log(pickedGiveItems);
})
.catch((err) => console.log('Not found related to Items'));
this.setState({ loading: false });
}
You also can't await a react state update since it isn't an async function nor does it return a Promise. Just provide an initial true loading state and toggle false when the fetch request resolves.
class Give_Item_List extends Component {
constructor(props) {
super(props);
this.state = {
loading: true
};
}
async componentDidMount() {
let pickedGiveItems;
await axios
.get(this.props.axiosUrl + 'giveitem/?category=' + this.props.category.id)
.then((res) => {
pickedGiveItems = res.data;
console.log(pickedGiveItems);
})
.catch((err) => console.log('Not found related to Items'));
this.setState({ loading: false });
}
render() {
if (this.state.loading) {
return <CircularProgress />;
}
return <h1>Give_Item_List</h1>;
}
}

How can I manage a list from Parent component in React and render it?

I have a reactjs application.
In this I want to manage a list from parent component.
This application can add a object to list, delete it from list and show added objects in a table.
My problem is that I can add an object, but must refresh the whole page that it is shown in the list.
The two way binding not work and I don't know how to implement it.
I hope you can help me.
class Wrap extends React.Component{
constructor(){
super();
this.state = {
player: []
};
}
render(){
return(
<div id ="wrapperComponent">
<Table/>
<Create />
</div>
);
}
}
class Table extends React.Component {
constructor(props) {
super(props);
this.state = {
player: []
};
this.deletePlayer = this.deletePlayer.bind(this);
}
componentDidMount() {
axios.get('http://localhost:8081/player')
.then(res => {
this.setState({ player: res.data });
console.log(this.state.player);
});
}
deletePlayer(id) {
fetch(`http://localhost:8081/player/${id}`, {
method: 'DELETE',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}).then(() => {
let updatedPlayers = [...this.state.player].filter(i => i.id !== id);
this.setState({player: updatedPlayers});
});
}
class Create extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
ownerid: ''
};
}
onChange = (e) => {
const state = this.state
state[e.target.name] = e.target.value;
this.setState(state);
}
onSubmit = (e) => {
e.preventDefault();
const { name, ownerid} = this.state;
axios.post('http://localhost:8081/player', { name, ownerid})
.then(() => this.setState(() => ({
})))
}
```
Add your .get call in a method in parent component and pass it as props. Use it to refresh your list.
class Wrap extends React.Component {
constructor() {
super();
this.state = {
players: []
};
}
getData = () => {
axios.get('http://localhost:8081/player')
.then(res => {
this.setState({ players: res.data });
});
}
removePlayerFromState = (id) => {
let updatedPlayers = [...this.state.players].filter(i => i.id !== id);
this.setState({players: updatedPlayers});
}
render() {
return (
<div id="wrapperComponent">
<Table getData={this.getData} players={this.state.players} removePlayerFromState={this.removePlayerFromState}/>
<Create getData={this.getData}/>
</div>
);
}
}
class Table extends React.Component {
// use this.props.players
}
class Create extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
ownerid: ''
};
}
onChange = (e) => {
const state = this.state
state[e.target.name] = e.target.value;
this.setState(state);
}
onSubmit = (e) => {
e.preventDefault();
const { name, ownerid } = this.state;
axios.post('http://localhost:8081/player', { name, ownerid })
.then(() => this.props.getData())
}
}

Access value from function dispatch on component

I'm new to react.
I have a function, that need to refresh the state according with API request result on my component.
How can i access that value?
Code (Example):
LoginComponent.js
class Login extends React.Component {
constructor(props){
super(props)
this.state = {
username : '',
password : ''
}
}
submit = (e) => {
/* console.logging "Some response"*/
console.log(this.props.doLogin(this.state))
}
render(){
return (
<form onSubmit={this.submit}>/* some login element */</form>
)
}
}
export default connect(null, {LoginAction})(Login);
LoginAction.js
export function doLogin(state){
return dispatch => {
return axios.post('login', state).then(res =>{
return "Some response";
})
}
}
you can do like this
for example create axios.js
import axios from 'axios';
var instance = axios.create({
baseURL: 'https://www.',
timeout: 1000,
headers: {'Authorization': 'Bearer xxx'}
});
export default instance;
then in your another screen
import React from 'react';
import API from '../axios';
export default class Profile extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: false,
feedback: "",
id: "",
errors: {},
};
}
postComment = () => {
API.post(`/new-comment`, {
id: this.state.id,
feedback: this.state.feedback,
})
.then(res => res.data)
.then((response)=> {
this.setState({
feedback: '',
error: response.error || null,
})
}).catch(error => {console.log(error), this.setState({ error});});
}

How to use state parameter in fetch url correctly?

Hello I have problem to set state variable in url parameter. I have tried few example I found in internet, but no one works for me.
I tried this:
constructor(props) {
super(props);
this.state = {
channelId: []
};
}
componentDidMount() {
this.setState({ channelId: '1ae2275e-2ca2-42cb-be13-e97b59fbae13' });
}
componentWillMount() {
fetch(
`http://localhost:8080/api/channel/${this.state.channelId}`)
.then...
And this:
constructor(props) {
super(props);
this.state = {
channelId: []
};
componentDidMount() {
this.setState({ channelId: '1ae2275e-2ca2-42cb-be13-e97b59fbae13' });
}
componentWillMount() {
fetch(
`http://localhost:8080/api/channel/'+this.state.channelId)
.then...
None of them are setting value in url. Maybe someone could tell me what I am doing wrong?
componentWillMount called before componentDidMount
-> so in componentWillMount, this.state.channelId = []
I think, you should set state of channelId in ComponentWillMount and call api in componentDidMount
constructor(props) {
super(props);
this.state = {
channelId: ''
};
componentWillMount() {
this.setState({ channelId: '1ae2275e-2ca2-42cb-be13-e97b59fbae13' });
}
componentDidMount() {
fetch(
`http://localhost:8080/api/channel/'+this.state.channelId)
.then...
And with react 16, react doesn't recommend using componentWillMount in new code (Details: https://reactjs.org/docs/react-component.html#unsafe_componentwillmount)
So the first thing is to set channelId to a string and not an array.
constructor(props) {
super(props);
this.state = {
channelId: ''
}
Let me ask why you want to use componentWillMount... From my experience, it sometimes adds a lifecycle that is not necessarily useful.
Have you tried
constructor(props) {
super(props);
this.state = {
channelId: ''
};
componentDidMount() {
this.getChannelId()
}
getChannelId() {
this.setState({
channelId: '1ae2275e-2ca2-42cb-be13-e97b59fbae13'
});
return fetch( `http://localhost:8080/api/channel/${this.state.channelId}`)
.then(res => {
// your code
})
}
?
I used a "similar" approach for an app of mine:
import React, { Component } from 'react';
import { connect} from 'react-redux';
import { API_BASE_URL } from '../config';
import { Weekday, Weekendday } from './Day';
import './Availability.css';
const currentUserId = localStorage.getItem("id");
export class Availability extends Component {
constructor(props) {
super(props);
this.state = {
availability: {},
loading: false,
error: null
};
}
componentDidMount() {
this.loadAvailability()
}
loadAvailability() {
this.setState({
loading: true
});
return fetch(`${API_BASE_URL}/employee/${currentUserId}/availability`)
.then(res => {
if (!res.ok) {
return Promise.reject(res.statusText);
}
return res.json();
})
.then(availability => {
console.log(availability)
this.setState({
availability,
loading: false
})
})
.catch(err => {
this.setState({
error: 'Could not load availability list',
load: false
})
console.log(this.state.error, err)
})
}
...
Also do you mind sharing the rest of your code for that component so we can see when you need another change of state?
Thanks!

Resources