How to get updated States at first time? - reactjs

I am using react states to store data that I am getting through axios from API. And I am changing some of the key values in my react states. those states are getting updated but not getting rendered those updated states.
constructor(props) {
super(props);
this.state = {
NewOrders:[],
}
this.getNewOrders();
}
getNewOrders = async () => {
let data = await api.get(`SellerOrdersAPI/${store.getState().auth.user.id}/`).then(({data})=>data);
data.map(a =>
this.get(a)
)
console.log(this.state.NewOrders)
this.setState({NewOrders:data})
this.testt()
}
get = async(a) => {
let data1 = await itemApi.get(`/${a.item}/`).then(({data})=>data);
a.item = data1.title
}
here in console.log item value got updated but I can not render this newly updated value.
If I perform some operation on this component then this value (22) got changed by new value. but on start I can not access that.

Call getNewOrders in componentDidMount instead of constructor
componentDidMount(){
this.getNewOrders();
}

Related

Accessing JSON Array Data in React.js/Next.js Combo

Given an API which returns JSON data like:
["posts":
{"id":1,
"name":"example",
"date":"exampledate",
"content":"examplecontent",
"author":"exampleauthor"},
{"id":2,
..]
The length of the array is unknown.
I am fetching data via isomorphic-fetch like this:
displayPosts.getInitialProps = async function() {
const res = await fetch('.../post');
const data = await res.json();
return{
posts: data.posts
}
}
which is working (console.log.stringify(data)).
Now i want to display such posts on my displayPosts page.
Therefore i am using the following React Component.
class Posts extends React.Component {
stat = {
// here i don't know how to set the state
}
render() {
return (
// i want to render the data here
);
}
}
export default Posts;
Question: How do i set a state, so that i can neatly display every post in my displayPosts.js page with
<Posts posts={props.Posts}/>
?
class Posts extends React.Component {
state = {
posts: []
}
componentDidMount() {
this.savePosts();
}
componentDidUpdate() {
this.savePosts();
}
savePosts = () => {
if(this.props.posts){
//do any other processing here first if you like
this.setState({
posts: this.props.posts
});
}
}
You probably don't need to save the posts in state, since you could just pull them from props directly. But if you need to process or transform them somehow, it might make sense.
In either case, you just hook into the lifecycle methods to do this.
Note: This will set the state every time the component updates. Often you only want to update the state when that specific prop changes. If so, you can first compare the old and new props to see if it has changed in a way that means you want to update your state.

setState does not trigger update - reactJs

I'm working with socket.io and react. I set up the listener in componentDidMount() and somehow the setState() function does not trigger the update. When i log the data, i can see the data sent from server. Here is my code:
this.state = {
list: []
};
public componentDidMount() {
this.socket = io('https://mybackendurl.com');
this.socket.on('an-event', data => {
console.log(data);
const list = [...this.state.list];
const updatedItemIndex = list.findIndex(
d => d.id === data.id
) as number;
list[updatedItemIndex].approvedBy = data.approvedBy;
this.setState({ list });
});
}
Can someone tell me what is the problem and how can solve this?
ComponentDidMount triggers once after the component loaded. You need to use componentDidUpdate()
And you should check
https://reactjs.org/docs/state-and-lifecycle.html and https://reactjs.org/docs/react-component.html
I can't say with full confidence that this would cause react to not see the state diff, but you are technically mutating state, which may cause react to see the old mutated state as matching the new updated state and choose not to re-render.
You do const list = [...this.state.list] to create a new list array which is good, but the nested object that you update will still be the previous reference. Try creating a new nested object as well.
this.socket.on('an-event', data => {
const list = [...this.state.list.map(item => ({...item})]; // create new object
const updatedItemIndex = list.findIndex(
d => d.id === data.id
) as number;
list[updatedItemIndex].approvedBy = data.approvedBy;
this.setState({ list });
});

React.JS State Update with Socket.io session data

I'm trying to update the state of a react app with data from a websocket and it all works but the issue is this:
In the view where I monitor the users currently logged in, the state is only reflecting the second to last update and not the last. If I refresh the page the data (I'm passing a current_url) gets updated but if I navigate to the page from another page, the previous url is shown instead of the current. I'm assuming that the state array is being updated only after the component renders and showing an old state.
I've tried using the setState callback to forceUpdate() but this doesn't seem to work. Any help would be very much appreciated. Thanks.
class UsersLoggedIn extends Component {
constructor(props) {
super(props);
this.state = {
usersLoggedIn: []
}
}
getUsersLogged() {
const socketIo = SocketIO();
if (typeof socketIo === 'object') {
socketIo.emit('getUsersLogged', (data) => {
const usersLoggedIn = [];
// groups the data from the socket by session id.
for (let id in data) {
let temp = [];
for (let socketId in data[id]) {
temp.push(data[id][socketId]);
}
usersLoggedIn.push({
...temp[0],
children: temp
});
}
this.setState({usersLoggedIn}, () => {
this.forceUpdate();
});
});
}
}
componentDidMount() {
// we need to pass data to the socket here.
const socketIo = SocketIO();
if (typeof socketIo === 'object') {
socketIo.on('loadUserLogged', (data) => {
this.getUsersLogged();
});
}
}

Uncaught (in promise) TypeError: this.setState is not a function

In my parent component, I'm loading data from a json file and using it to set state. Using react-router, I then pass the state down to a child component which renders the data in a route. This behavior works as expected. However, when I attempt to refresh the route, the parent component's state (and the child component's props) are lost, and the page throws an undefined error.
I've attempted to call the data loading functions from the parent component in the ComponentDidMount lifecycle method of the child component, but the app throws the error Uncaught (in promise) TypeError: this.setState is not a function.
The parent component code:
async loadWorldData() {
await axios.get("../factbook.json")
.then(res => {
let Data = res && res.data.countries;
Data = Object.values(Data).map(country => country.data) || [];
let newData = this.removeNull(Object.values(Data));
this.setState({ worldData: newData})
});
}
The child component code:
componentWillMount = () => {
this.props.loadWorldData();
}
I don't know another way to reload the app state without calling the parent function in the lifecycle methods of the child.
Try this: This is probably a binding issue.
loadWorldData = async() => {
const res = await axios.get("../factbook.json")
let data = res && res.data.countries;
data = Object.values(Data).map(country => country.data) || [];
let newData = this.removeNull(Object.values(Data));
this.setState({ worldData: newData });
}
Why is this not working?
In order to use setState, you must have access to this. Normal functions are not bound to this. There are two options to fix this issue:
First: Bind the function to this inside the constructor.
class App extends React.Component {
constructor(props) {
super(props);
this.loadWorldData = this.loadWorldData.bind(this);
}
}
Second: Fat Arrow functions:
Since Fat arrow functions are bound to this, you don't have to worry about binding them inside the constructor as denoted by the first example.
async loadWorldData() {
const self = this;
await axios.get("../factbook.json")
.then(res => {
let Data = res && res.data.countries;
Data = Object.values(Data).map(country => country.data) ||
[];
let newData = this.removeNull(Object.values(Data));
self.setState({ worldData: newData})
});
}
you can delete async await you don't need them .

React component is rendering but not updating when state is updating

React component is showing data when state is null but, when its getting data then its not updating the content of the view.
constructor(props){
super(props);
this.state = {
post: null
}
this.getTotalDownloadSize = this.getTotalDownloadSize.bind(this);
}
componentWillMount(){
const {match} = this.props;
const postId = _.get(match, 'params.id');
getDownloadInfo(postId).then((response) => {
this.setState({
post: _.get(response, 'data')
});
}).catch((err) => {
console.log("an error while fetching data", err);
})
}
inside my render i am getting null value for render(){
render(){
const {post} = this.state;
console.log{post};
const files = _.get(post, 'files', []);
)
initially its showing the null value but after it has value but its not updating the content of the view.
can anyone help me with this.
thanks in advance.
componentDidMount is place where you can place request logic.
componentDidMount() {
const {match} = this.props;
const postId = _.get(match, 'params.id');
getDownloadInfo(postId).then((response) => {
this.setState((state) => ({ post: _.get(response, 'data')}));
}).catch((err) => {
console.log("an error while fetching data", err);
})
}
If your data came from an asynchronous request you should use componentDidMount
Invoked once, only on the client (not on the server), immediately
after the initial rendering occurs. At this point in the lifecycle,
you can access any refs to your children (e.g., to access the
underlying DOM representation). The componentDidMount() method of
child components is invoked before that of parent components.
If you want to integrate with other JavaScript frameworks, set timers
using setTimeout or setInterval, or send AJAX requests, perform those
operations in this method.

Resources