setState not updating the state object
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I'm learning react from the book full stack react. In one of the examples votingapp where you have products and a button to vote for the product. That button supposes to increase the number of votes for that product and I store the votes number in a component Parent's state and display it in a child component. That voting feature is not working.
I created Parent component where it displays child component that present product description, id, color and votes (the number of votes the product received)
import React, { Component } from 'react';
import './App.css';
import Product from "./Product";
var products = [
{
id: 1,
name: "one",
color: "blue",
votes:0
},
{
id: 2,
name: "two",
color: "green",
votes : 0
},
{
id: 3,
name: "three",
color: "Red",
votes : 1
}
];
class App extends Component {
//this function will be passed to child component so the child can pass any data needed back to the parent using function argument.
handleProductUpVote(productId) {
console.log("Product #" + " " +productId + " was upvoted")
};
render() {
const productComponents = products.map((product) => {
return <Product
key={"product-" + product.id}
id={product.id}
name={product.name}
color={product.color}
votes={product.votes}
/*this is how we pass the function from parent to the child as a prop*/
onVote={this.handleProductUpVote}
/>
});
return (
<div className="App">
{productComponents}
</div>
);
}
}
export default App;
and here is my child component where it renders the product details
import React, { Component } from 'react';
class Product extends Component {
constructor(props) {
super(props);
this.handleUpVote = this.handleUpVote.bind(this);
}
//using the function passed from parent in a child. We pass any data needed back to parent component using parent's function arugments
// invoke this function using onClick event inside the button
handleUpVote() {
this.props.onVote(this.props.id);
};
render() {
return (
<div>
<p> name: {this.props.name} </p>
<p> MYcolor: {this.props.color} </p>
{/*invoke the function using onClick so it will invoke handleUpVote that will update the prop and pass the data back to parent*/}
<button onClick={this.handleUpVote}> Upvote Me </button>
<p>{this.props.votes}</p>
<hr></hr>
</div>
)
}
};
export default Product;
this is working and I log to the console the message when I hit the button "Upvoteme"
But When I'm trying to move the setup to use state. It doesn't work Here is the parent component with the state and setState. When I click on the vote button nothing happens to the vote count.
import React, { Component } from 'react';
import './App.css';
import Child from "./Child";
var productseed = [
{
id: 1,
name: "one",
color: "blue",
votes: 0
},
{
id: 2,
name: "two",
color: "green",
votes : 0
},
{
id: 3,
name: "three",
color: "Red",
votes : 1
}
];
class Parent extends Component {
constructor(props) {
super(props);
this.state = {
products: ,
};
this.handleProductUpVote = this.handleProductUpVote.bind(this);
}
componentDidMount() {
this.setState ({ products: productseed });
}
//this function will be passed to child component so the child can pass any data needed back to the parent using function argument.
handleProductUpVote(productId) {
// updating the vote in state
const nextProducts = this.state.products.map((product) => {
if (product.id === productId) {
return Object.assign({}, product, {
votes: product.votes + 1,
});
} else {
return product
}
});
this.setState({
products: nextProducts,
});
}
render() {
const productComponents = productseed.map((product) => {
return <Child
key={"product-" + product.id}
id={product.id}
name={product.name}
color={product.color}
votes={product.votes}
/*this is how we pass the function from parent to the child as a prop*/
onVote={this.handleProductUpVote}
/>
});
return (
<div className="App">
parent
{productComponents}
</div>
);
}
}
export default Parent;
The line below suppose to point to the products in the state but when I highlight it, it doesn't highlight the products in the this.state.
The consolelog is logging the message to my developer console. This is the issue, products in this.setState isn't pointing to the this.state.products and therefore not updating the state.
componentDidMount() {
this.setState({ products: productseed });
console.log("this products not pointing to the this.state.products, why?")
}
I read every question on stackoverflow related to setState not working and yet I have the same problem. If you an expert with react and able to take a look at this and figure out where is the issue, I would be so grateful. I'm unable to figure out when I assigned the this.setState({products: productseed}) and it doesn't update the state. I spent almost the past 4 hours reading and researching, please help.
reactjs setstate
add a comment |
I'm learning react from the book full stack react. In one of the examples votingapp where you have products and a button to vote for the product. That button supposes to increase the number of votes for that product and I store the votes number in a component Parent's state and display it in a child component. That voting feature is not working.
I created Parent component where it displays child component that present product description, id, color and votes (the number of votes the product received)
import React, { Component } from 'react';
import './App.css';
import Product from "./Product";
var products = [
{
id: 1,
name: "one",
color: "blue",
votes:0
},
{
id: 2,
name: "two",
color: "green",
votes : 0
},
{
id: 3,
name: "three",
color: "Red",
votes : 1
}
];
class App extends Component {
//this function will be passed to child component so the child can pass any data needed back to the parent using function argument.
handleProductUpVote(productId) {
console.log("Product #" + " " +productId + " was upvoted")
};
render() {
const productComponents = products.map((product) => {
return <Product
key={"product-" + product.id}
id={product.id}
name={product.name}
color={product.color}
votes={product.votes}
/*this is how we pass the function from parent to the child as a prop*/
onVote={this.handleProductUpVote}
/>
});
return (
<div className="App">
{productComponents}
</div>
);
}
}
export default App;
and here is my child component where it renders the product details
import React, { Component } from 'react';
class Product extends Component {
constructor(props) {
super(props);
this.handleUpVote = this.handleUpVote.bind(this);
}
//using the function passed from parent in a child. We pass any data needed back to parent component using parent's function arugments
// invoke this function using onClick event inside the button
handleUpVote() {
this.props.onVote(this.props.id);
};
render() {
return (
<div>
<p> name: {this.props.name} </p>
<p> MYcolor: {this.props.color} </p>
{/*invoke the function using onClick so it will invoke handleUpVote that will update the prop and pass the data back to parent*/}
<button onClick={this.handleUpVote}> Upvote Me </button>
<p>{this.props.votes}</p>
<hr></hr>
</div>
)
}
};
export default Product;
this is working and I log to the console the message when I hit the button "Upvoteme"
But When I'm trying to move the setup to use state. It doesn't work Here is the parent component with the state and setState. When I click on the vote button nothing happens to the vote count.
import React, { Component } from 'react';
import './App.css';
import Child from "./Child";
var productseed = [
{
id: 1,
name: "one",
color: "blue",
votes: 0
},
{
id: 2,
name: "two",
color: "green",
votes : 0
},
{
id: 3,
name: "three",
color: "Red",
votes : 1
}
];
class Parent extends Component {
constructor(props) {
super(props);
this.state = {
products: ,
};
this.handleProductUpVote = this.handleProductUpVote.bind(this);
}
componentDidMount() {
this.setState ({ products: productseed });
}
//this function will be passed to child component so the child can pass any data needed back to the parent using function argument.
handleProductUpVote(productId) {
// updating the vote in state
const nextProducts = this.state.products.map((product) => {
if (product.id === productId) {
return Object.assign({}, product, {
votes: product.votes + 1,
});
} else {
return product
}
});
this.setState({
products: nextProducts,
});
}
render() {
const productComponents = productseed.map((product) => {
return <Child
key={"product-" + product.id}
id={product.id}
name={product.name}
color={product.color}
votes={product.votes}
/*this is how we pass the function from parent to the child as a prop*/
onVote={this.handleProductUpVote}
/>
});
return (
<div className="App">
parent
{productComponents}
</div>
);
}
}
export default Parent;
The line below suppose to point to the products in the state but when I highlight it, it doesn't highlight the products in the this.state.
The consolelog is logging the message to my developer console. This is the issue, products in this.setState isn't pointing to the this.state.products and therefore not updating the state.
componentDidMount() {
this.setState({ products: productseed });
console.log("this products not pointing to the this.state.products, why?")
}
I read every question on stackoverflow related to setState not working and yet I have the same problem. If you an expert with react and able to take a look at this and figure out where is the issue, I would be so grateful. I'm unable to figure out when I assigned the this.setState({products: productseed}) and it doesn't update the state. I spent almost the past 4 hours reading and researching, please help.
reactjs setstate
if you move this console.logconsole.log("this products not pointing to the this.state.products, why?")
into therender()
do you see the expected result? Also, what IS logging? if it's not pointing to the products in state, what is it pointing to?
– HolyMoly
Jan 4 at 18:54
1
Keep in mind thatsetState
is asynchronous, so if you callsetState
and then immediately call something likeconsole.log
, the state may not have changed yet... That is why @HolyMolyreccomends logging in render instead. See the docs
– Garrett Motzner
Jan 4 at 19:20
when your child component runs it's callback functiononVote
it updates the state of the parent. State changes trigger a re-render. I am not sure, but am pretty sure that because the component is re-rendering, all the lifecycle events cycle, includingcomponentDidMount
which in your case is setting the value ofthis.state.products
to theseedProducts
...this.setState ({ products: productseed });
– HolyMoly
Jan 4 at 19:21
add a comment |
I'm learning react from the book full stack react. In one of the examples votingapp where you have products and a button to vote for the product. That button supposes to increase the number of votes for that product and I store the votes number in a component Parent's state and display it in a child component. That voting feature is not working.
I created Parent component where it displays child component that present product description, id, color and votes (the number of votes the product received)
import React, { Component } from 'react';
import './App.css';
import Product from "./Product";
var products = [
{
id: 1,
name: "one",
color: "blue",
votes:0
},
{
id: 2,
name: "two",
color: "green",
votes : 0
},
{
id: 3,
name: "three",
color: "Red",
votes : 1
}
];
class App extends Component {
//this function will be passed to child component so the child can pass any data needed back to the parent using function argument.
handleProductUpVote(productId) {
console.log("Product #" + " " +productId + " was upvoted")
};
render() {
const productComponents = products.map((product) => {
return <Product
key={"product-" + product.id}
id={product.id}
name={product.name}
color={product.color}
votes={product.votes}
/*this is how we pass the function from parent to the child as a prop*/
onVote={this.handleProductUpVote}
/>
});
return (
<div className="App">
{productComponents}
</div>
);
}
}
export default App;
and here is my child component where it renders the product details
import React, { Component } from 'react';
class Product extends Component {
constructor(props) {
super(props);
this.handleUpVote = this.handleUpVote.bind(this);
}
//using the function passed from parent in a child. We pass any data needed back to parent component using parent's function arugments
// invoke this function using onClick event inside the button
handleUpVote() {
this.props.onVote(this.props.id);
};
render() {
return (
<div>
<p> name: {this.props.name} </p>
<p> MYcolor: {this.props.color} </p>
{/*invoke the function using onClick so it will invoke handleUpVote that will update the prop and pass the data back to parent*/}
<button onClick={this.handleUpVote}> Upvote Me </button>
<p>{this.props.votes}</p>
<hr></hr>
</div>
)
}
};
export default Product;
this is working and I log to the console the message when I hit the button "Upvoteme"
But When I'm trying to move the setup to use state. It doesn't work Here is the parent component with the state and setState. When I click on the vote button nothing happens to the vote count.
import React, { Component } from 'react';
import './App.css';
import Child from "./Child";
var productseed = [
{
id: 1,
name: "one",
color: "blue",
votes: 0
},
{
id: 2,
name: "two",
color: "green",
votes : 0
},
{
id: 3,
name: "three",
color: "Red",
votes : 1
}
];
class Parent extends Component {
constructor(props) {
super(props);
this.state = {
products: ,
};
this.handleProductUpVote = this.handleProductUpVote.bind(this);
}
componentDidMount() {
this.setState ({ products: productseed });
}
//this function will be passed to child component so the child can pass any data needed back to the parent using function argument.
handleProductUpVote(productId) {
// updating the vote in state
const nextProducts = this.state.products.map((product) => {
if (product.id === productId) {
return Object.assign({}, product, {
votes: product.votes + 1,
});
} else {
return product
}
});
this.setState({
products: nextProducts,
});
}
render() {
const productComponents = productseed.map((product) => {
return <Child
key={"product-" + product.id}
id={product.id}
name={product.name}
color={product.color}
votes={product.votes}
/*this is how we pass the function from parent to the child as a prop*/
onVote={this.handleProductUpVote}
/>
});
return (
<div className="App">
parent
{productComponents}
</div>
);
}
}
export default Parent;
The line below suppose to point to the products in the state but when I highlight it, it doesn't highlight the products in the this.state.
The consolelog is logging the message to my developer console. This is the issue, products in this.setState isn't pointing to the this.state.products and therefore not updating the state.
componentDidMount() {
this.setState({ products: productseed });
console.log("this products not pointing to the this.state.products, why?")
}
I read every question on stackoverflow related to setState not working and yet I have the same problem. If you an expert with react and able to take a look at this and figure out where is the issue, I would be so grateful. I'm unable to figure out when I assigned the this.setState({products: productseed}) and it doesn't update the state. I spent almost the past 4 hours reading and researching, please help.
reactjs setstate
I'm learning react from the book full stack react. In one of the examples votingapp where you have products and a button to vote for the product. That button supposes to increase the number of votes for that product and I store the votes number in a component Parent's state and display it in a child component. That voting feature is not working.
I created Parent component where it displays child component that present product description, id, color and votes (the number of votes the product received)
import React, { Component } from 'react';
import './App.css';
import Product from "./Product";
var products = [
{
id: 1,
name: "one",
color: "blue",
votes:0
},
{
id: 2,
name: "two",
color: "green",
votes : 0
},
{
id: 3,
name: "three",
color: "Red",
votes : 1
}
];
class App extends Component {
//this function will be passed to child component so the child can pass any data needed back to the parent using function argument.
handleProductUpVote(productId) {
console.log("Product #" + " " +productId + " was upvoted")
};
render() {
const productComponents = products.map((product) => {
return <Product
key={"product-" + product.id}
id={product.id}
name={product.name}
color={product.color}
votes={product.votes}
/*this is how we pass the function from parent to the child as a prop*/
onVote={this.handleProductUpVote}
/>
});
return (
<div className="App">
{productComponents}
</div>
);
}
}
export default App;
and here is my child component where it renders the product details
import React, { Component } from 'react';
class Product extends Component {
constructor(props) {
super(props);
this.handleUpVote = this.handleUpVote.bind(this);
}
//using the function passed from parent in a child. We pass any data needed back to parent component using parent's function arugments
// invoke this function using onClick event inside the button
handleUpVote() {
this.props.onVote(this.props.id);
};
render() {
return (
<div>
<p> name: {this.props.name} </p>
<p> MYcolor: {this.props.color} </p>
{/*invoke the function using onClick so it will invoke handleUpVote that will update the prop and pass the data back to parent*/}
<button onClick={this.handleUpVote}> Upvote Me </button>
<p>{this.props.votes}</p>
<hr></hr>
</div>
)
}
};
export default Product;
this is working and I log to the console the message when I hit the button "Upvoteme"
But When I'm trying to move the setup to use state. It doesn't work Here is the parent component with the state and setState. When I click on the vote button nothing happens to the vote count.
import React, { Component } from 'react';
import './App.css';
import Child from "./Child";
var productseed = [
{
id: 1,
name: "one",
color: "blue",
votes: 0
},
{
id: 2,
name: "two",
color: "green",
votes : 0
},
{
id: 3,
name: "three",
color: "Red",
votes : 1
}
];
class Parent extends Component {
constructor(props) {
super(props);
this.state = {
products: ,
};
this.handleProductUpVote = this.handleProductUpVote.bind(this);
}
componentDidMount() {
this.setState ({ products: productseed });
}
//this function will be passed to child component so the child can pass any data needed back to the parent using function argument.
handleProductUpVote(productId) {
// updating the vote in state
const nextProducts = this.state.products.map((product) => {
if (product.id === productId) {
return Object.assign({}, product, {
votes: product.votes + 1,
});
} else {
return product
}
});
this.setState({
products: nextProducts,
});
}
render() {
const productComponents = productseed.map((product) => {
return <Child
key={"product-" + product.id}
id={product.id}
name={product.name}
color={product.color}
votes={product.votes}
/*this is how we pass the function from parent to the child as a prop*/
onVote={this.handleProductUpVote}
/>
});
return (
<div className="App">
parent
{productComponents}
</div>
);
}
}
export default Parent;
The line below suppose to point to the products in the state but when I highlight it, it doesn't highlight the products in the this.state.
The consolelog is logging the message to my developer console. This is the issue, products in this.setState isn't pointing to the this.state.products and therefore not updating the state.
componentDidMount() {
this.setState({ products: productseed });
console.log("this products not pointing to the this.state.products, why?")
}
I read every question on stackoverflow related to setState not working and yet I have the same problem. If you an expert with react and able to take a look at this and figure out where is the issue, I would be so grateful. I'm unable to figure out when I assigned the this.setState({products: productseed}) and it doesn't update the state. I spent almost the past 4 hours reading and researching, please help.
reactjs setstate
reactjs setstate
edited Jan 4 at 20:07
BreakBB
745515
745515
asked Jan 4 at 18:46
MarcoMarco
112316
112316
if you move this console.logconsole.log("this products not pointing to the this.state.products, why?")
into therender()
do you see the expected result? Also, what IS logging? if it's not pointing to the products in state, what is it pointing to?
– HolyMoly
Jan 4 at 18:54
1
Keep in mind thatsetState
is asynchronous, so if you callsetState
and then immediately call something likeconsole.log
, the state may not have changed yet... That is why @HolyMolyreccomends logging in render instead. See the docs
– Garrett Motzner
Jan 4 at 19:20
when your child component runs it's callback functiononVote
it updates the state of the parent. State changes trigger a re-render. I am not sure, but am pretty sure that because the component is re-rendering, all the lifecycle events cycle, includingcomponentDidMount
which in your case is setting the value ofthis.state.products
to theseedProducts
...this.setState ({ products: productseed });
– HolyMoly
Jan 4 at 19:21
add a comment |
if you move this console.logconsole.log("this products not pointing to the this.state.products, why?")
into therender()
do you see the expected result? Also, what IS logging? if it's not pointing to the products in state, what is it pointing to?
– HolyMoly
Jan 4 at 18:54
1
Keep in mind thatsetState
is asynchronous, so if you callsetState
and then immediately call something likeconsole.log
, the state may not have changed yet... That is why @HolyMolyreccomends logging in render instead. See the docs
– Garrett Motzner
Jan 4 at 19:20
when your child component runs it's callback functiononVote
it updates the state of the parent. State changes trigger a re-render. I am not sure, but am pretty sure that because the component is re-rendering, all the lifecycle events cycle, includingcomponentDidMount
which in your case is setting the value ofthis.state.products
to theseedProducts
...this.setState ({ products: productseed });
– HolyMoly
Jan 4 at 19:21
if you move this console.log
console.log("this products not pointing to the this.state.products, why?")
into the render()
do you see the expected result? Also, what IS logging? if it's not pointing to the products in state, what is it pointing to?– HolyMoly
Jan 4 at 18:54
if you move this console.log
console.log("this products not pointing to the this.state.products, why?")
into the render()
do you see the expected result? Also, what IS logging? if it's not pointing to the products in state, what is it pointing to?– HolyMoly
Jan 4 at 18:54
1
1
Keep in mind that
setState
is asynchronous, so if you call setState
and then immediately call something like console.log
, the state may not have changed yet... That is why @HolyMolyreccomends logging in render instead. See the docs– Garrett Motzner
Jan 4 at 19:20
Keep in mind that
setState
is asynchronous, so if you call setState
and then immediately call something like console.log
, the state may not have changed yet... That is why @HolyMolyreccomends logging in render instead. See the docs– Garrett Motzner
Jan 4 at 19:20
when your child component runs it's callback function
onVote
it updates the state of the parent. State changes trigger a re-render. I am not sure, but am pretty sure that because the component is re-rendering, all the lifecycle events cycle, including componentDidMount
which in your case is setting the value of this.state.products
to the seedProducts
... this.setState ({ products: productseed });
– HolyMoly
Jan 4 at 19:21
when your child component runs it's callback function
onVote
it updates the state of the parent. State changes trigger a re-render. I am not sure, but am pretty sure that because the component is re-rendering, all the lifecycle events cycle, including componentDidMount
which in your case is setting the value of this.state.products
to the seedProducts
... this.setState ({ products: productseed });
– HolyMoly
Jan 4 at 19:21
add a comment |
1 Answer
1
active
oldest
votes
Your problem lies in the render method of your Parent
component. You're iterating over the productseeds
array instead of your state. Since you're updating the state and not the seed array react sees no reason to rerender anything and therefore nothing changes.
So if you change that line from
const productComponents = productseed.map((product) => {...
to
const productComponents = this.state.products.map((product) => {...
you should be fine.
Moreover about your:
The line below suppose to point to the products in the state but when I highlight it, it doesn't highlight the products in the this.state.
This is just something related to the IDE you're using and nothing specific about react. You're passing an object with attributes and most IDEs (or all (?)) don't connect the combination with this.setState
to the state object.
Thank you. It does work with your help. I appreciate it. So to understand this: after doing what you said, I now pull the data from the state and I update the state with handleProductUpVote function. The question then: why use compnentDidMount method? I read about the method and I understand it, I'm questioning the reason to use because I pulled the data from productComponents to build my interface and then clicked the button and at the end of the handleProductUpVote function I used this.setState to update it with the vote new state.
– Marco
Jan 4 at 23:58
If I remove the componentDidMount, the whole interface disappear.
– Marco
Jan 5 at 0:01
You're welcome. You should usecomponentDidMount
whenever you're fetching data from an external source and/or if you initial state is empty. The reason is thatthis.setState
is an asynchronous method and react doesn't promise to update the state "right now". You could remove thecomponentDidMount
method and set the initial state to your productseeds. But you still have to usethis.state.products.map
– BreakBB
Jan 5 at 8:52
Your answer is so precise. It reflects your deep understanding of react. Happy new year and thank you. Gratitude is all i can offer you but hopefully i'll be able to pay it forward in the near future.
– Marco
Jan 5 at 18:00
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54044450%2fsetstate-not-updating-the-state-object%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your problem lies in the render method of your Parent
component. You're iterating over the productseeds
array instead of your state. Since you're updating the state and not the seed array react sees no reason to rerender anything and therefore nothing changes.
So if you change that line from
const productComponents = productseed.map((product) => {...
to
const productComponents = this.state.products.map((product) => {...
you should be fine.
Moreover about your:
The line below suppose to point to the products in the state but when I highlight it, it doesn't highlight the products in the this.state.
This is just something related to the IDE you're using and nothing specific about react. You're passing an object with attributes and most IDEs (or all (?)) don't connect the combination with this.setState
to the state object.
Thank you. It does work with your help. I appreciate it. So to understand this: after doing what you said, I now pull the data from the state and I update the state with handleProductUpVote function. The question then: why use compnentDidMount method? I read about the method and I understand it, I'm questioning the reason to use because I pulled the data from productComponents to build my interface and then clicked the button and at the end of the handleProductUpVote function I used this.setState to update it with the vote new state.
– Marco
Jan 4 at 23:58
If I remove the componentDidMount, the whole interface disappear.
– Marco
Jan 5 at 0:01
You're welcome. You should usecomponentDidMount
whenever you're fetching data from an external source and/or if you initial state is empty. The reason is thatthis.setState
is an asynchronous method and react doesn't promise to update the state "right now". You could remove thecomponentDidMount
method and set the initial state to your productseeds. But you still have to usethis.state.products.map
– BreakBB
Jan 5 at 8:52
Your answer is so precise. It reflects your deep understanding of react. Happy new year and thank you. Gratitude is all i can offer you but hopefully i'll be able to pay it forward in the near future.
– Marco
Jan 5 at 18:00
add a comment |
Your problem lies in the render method of your Parent
component. You're iterating over the productseeds
array instead of your state. Since you're updating the state and not the seed array react sees no reason to rerender anything and therefore nothing changes.
So if you change that line from
const productComponents = productseed.map((product) => {...
to
const productComponents = this.state.products.map((product) => {...
you should be fine.
Moreover about your:
The line below suppose to point to the products in the state but when I highlight it, it doesn't highlight the products in the this.state.
This is just something related to the IDE you're using and nothing specific about react. You're passing an object with attributes and most IDEs (or all (?)) don't connect the combination with this.setState
to the state object.
Thank you. It does work with your help. I appreciate it. So to understand this: after doing what you said, I now pull the data from the state and I update the state with handleProductUpVote function. The question then: why use compnentDidMount method? I read about the method and I understand it, I'm questioning the reason to use because I pulled the data from productComponents to build my interface and then clicked the button and at the end of the handleProductUpVote function I used this.setState to update it with the vote new state.
– Marco
Jan 4 at 23:58
If I remove the componentDidMount, the whole interface disappear.
– Marco
Jan 5 at 0:01
You're welcome. You should usecomponentDidMount
whenever you're fetching data from an external source and/or if you initial state is empty. The reason is thatthis.setState
is an asynchronous method and react doesn't promise to update the state "right now". You could remove thecomponentDidMount
method and set the initial state to your productseeds. But you still have to usethis.state.products.map
– BreakBB
Jan 5 at 8:52
Your answer is so precise. It reflects your deep understanding of react. Happy new year and thank you. Gratitude is all i can offer you but hopefully i'll be able to pay it forward in the near future.
– Marco
Jan 5 at 18:00
add a comment |
Your problem lies in the render method of your Parent
component. You're iterating over the productseeds
array instead of your state. Since you're updating the state and not the seed array react sees no reason to rerender anything and therefore nothing changes.
So if you change that line from
const productComponents = productseed.map((product) => {...
to
const productComponents = this.state.products.map((product) => {...
you should be fine.
Moreover about your:
The line below suppose to point to the products in the state but when I highlight it, it doesn't highlight the products in the this.state.
This is just something related to the IDE you're using and nothing specific about react. You're passing an object with attributes and most IDEs (or all (?)) don't connect the combination with this.setState
to the state object.
Your problem lies in the render method of your Parent
component. You're iterating over the productseeds
array instead of your state. Since you're updating the state and not the seed array react sees no reason to rerender anything and therefore nothing changes.
So if you change that line from
const productComponents = productseed.map((product) => {...
to
const productComponents = this.state.products.map((product) => {...
you should be fine.
Moreover about your:
The line below suppose to point to the products in the state but when I highlight it, it doesn't highlight the products in the this.state.
This is just something related to the IDE you're using and nothing specific about react. You're passing an object with attributes and most IDEs (or all (?)) don't connect the combination with this.setState
to the state object.
edited Jan 4 at 19:54
answered Jan 4 at 19:20
BreakBBBreakBB
745515
745515
Thank you. It does work with your help. I appreciate it. So to understand this: after doing what you said, I now pull the data from the state and I update the state with handleProductUpVote function. The question then: why use compnentDidMount method? I read about the method and I understand it, I'm questioning the reason to use because I pulled the data from productComponents to build my interface and then clicked the button and at the end of the handleProductUpVote function I used this.setState to update it with the vote new state.
– Marco
Jan 4 at 23:58
If I remove the componentDidMount, the whole interface disappear.
– Marco
Jan 5 at 0:01
You're welcome. You should usecomponentDidMount
whenever you're fetching data from an external source and/or if you initial state is empty. The reason is thatthis.setState
is an asynchronous method and react doesn't promise to update the state "right now". You could remove thecomponentDidMount
method and set the initial state to your productseeds. But you still have to usethis.state.products.map
– BreakBB
Jan 5 at 8:52
Your answer is so precise. It reflects your deep understanding of react. Happy new year and thank you. Gratitude is all i can offer you but hopefully i'll be able to pay it forward in the near future.
– Marco
Jan 5 at 18:00
add a comment |
Thank you. It does work with your help. I appreciate it. So to understand this: after doing what you said, I now pull the data from the state and I update the state with handleProductUpVote function. The question then: why use compnentDidMount method? I read about the method and I understand it, I'm questioning the reason to use because I pulled the data from productComponents to build my interface and then clicked the button and at the end of the handleProductUpVote function I used this.setState to update it with the vote new state.
– Marco
Jan 4 at 23:58
If I remove the componentDidMount, the whole interface disappear.
– Marco
Jan 5 at 0:01
You're welcome. You should usecomponentDidMount
whenever you're fetching data from an external source and/or if you initial state is empty. The reason is thatthis.setState
is an asynchronous method and react doesn't promise to update the state "right now". You could remove thecomponentDidMount
method and set the initial state to your productseeds. But you still have to usethis.state.products.map
– BreakBB
Jan 5 at 8:52
Your answer is so precise. It reflects your deep understanding of react. Happy new year and thank you. Gratitude is all i can offer you but hopefully i'll be able to pay it forward in the near future.
– Marco
Jan 5 at 18:00
Thank you. It does work with your help. I appreciate it. So to understand this: after doing what you said, I now pull the data from the state and I update the state with handleProductUpVote function. The question then: why use compnentDidMount method? I read about the method and I understand it, I'm questioning the reason to use because I pulled the data from productComponents to build my interface and then clicked the button and at the end of the handleProductUpVote function I used this.setState to update it with the vote new state.
– Marco
Jan 4 at 23:58
Thank you. It does work with your help. I appreciate it. So to understand this: after doing what you said, I now pull the data from the state and I update the state with handleProductUpVote function. The question then: why use compnentDidMount method? I read about the method and I understand it, I'm questioning the reason to use because I pulled the data from productComponents to build my interface and then clicked the button and at the end of the handleProductUpVote function I used this.setState to update it with the vote new state.
– Marco
Jan 4 at 23:58
If I remove the componentDidMount, the whole interface disappear.
– Marco
Jan 5 at 0:01
If I remove the componentDidMount, the whole interface disappear.
– Marco
Jan 5 at 0:01
You're welcome. You should use
componentDidMount
whenever you're fetching data from an external source and/or if you initial state is empty. The reason is that this.setState
is an asynchronous method and react doesn't promise to update the state "right now". You could remove the componentDidMount
method and set the initial state to your productseeds. But you still have to use this.state.products.map
– BreakBB
Jan 5 at 8:52
You're welcome. You should use
componentDidMount
whenever you're fetching data from an external source and/or if you initial state is empty. The reason is that this.setState
is an asynchronous method and react doesn't promise to update the state "right now". You could remove the componentDidMount
method and set the initial state to your productseeds. But you still have to use this.state.products.map
– BreakBB
Jan 5 at 8:52
Your answer is so precise. It reflects your deep understanding of react. Happy new year and thank you. Gratitude is all i can offer you but hopefully i'll be able to pay it forward in the near future.
– Marco
Jan 5 at 18:00
Your answer is so precise. It reflects your deep understanding of react. Happy new year and thank you. Gratitude is all i can offer you but hopefully i'll be able to pay it forward in the near future.
– Marco
Jan 5 at 18:00
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54044450%2fsetstate-not-updating-the-state-object%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
if you move this console.log
console.log("this products not pointing to the this.state.products, why?")
into therender()
do you see the expected result? Also, what IS logging? if it's not pointing to the products in state, what is it pointing to?– HolyMoly
Jan 4 at 18:54
1
Keep in mind that
setState
is asynchronous, so if you callsetState
and then immediately call something likeconsole.log
, the state may not have changed yet... That is why @HolyMolyreccomends logging in render instead. See the docs– Garrett Motzner
Jan 4 at 19:20
when your child component runs it's callback function
onVote
it updates the state of the parent. State changes trigger a re-render. I am not sure, but am pretty sure that because the component is re-rendering, all the lifecycle events cycle, includingcomponentDidMount
which in your case is setting the value ofthis.state.products
to theseedProducts
...this.setState ({ products: productseed });
– HolyMoly
Jan 4 at 19:21