admin管理员组文章数量:1317909
When I'm sending state of the child ponent to its parent ponent, React is sending old state to the parent ponent.
I want to send the updated state on every click on ListItem which is properly working and calling the function handleItemClick.
But when I'm calling sendStateToParent
. It is passing old state of it. Suppose I have clicked on ITEM1
, it is sending empty array[]
. Next I have clicked on ITEM2
, it is sending array [ITEM1]
.
Here I'm actually creating a multiselect dropdown. which also can act as single select based on props it is getting.
import React from 'react';
import ListItemComponent from './ListItem.jsx';
import DropDownButtonComponent from './DropDownButton.jsx';
import DropDownStyle from '../../../../css/sass/drop-down.scss';
module.exports = React.createClass({
handleClick: function () {
this.setState({open: !this.state.open});
},
getInitialState: function () {
return {
open: false,
//listItems: this.props.listItems,
selectedItems:[],
title: this.props.dropdownTitle
}
},
handleItemClick: function (item) {
var selectedItems = [];
if(this.props.multiple == true){
selectedItems = this.state.selectedItems;
if(selectedItems.indexOf(item)==-1){
selectedItems.push(item);
}else{
selectedItems.splice(selectedItems.indexOf(item),1)
}
this.setState({
title: this.state.selectedItems.length+" selected",
selectedItems: selectedItems
});
} else{
selectedItems = [];
selectedItems.push(item);
this.setState({
title: item,
selectedItems: selectedItems,
open: false
});
}
this.sendStateToParent();
},
sendStateToParent: function(){
this.props.ifListChanged(this);
},
handleTextChange: function (event) {
var filteredItems = [];
this.props.listItems.map(function(item){
if(item.toLowerCase().search(event.target.value.toLowerCase()) != -1){
filteredItems.push(item);
}
},this);
this.setState({
listItems: filteredItems
});
},
clearSelected: function(){
this.setState({
title: this.props.dropdownTitle,
selectedItems: [],
});
},
render: function () {
var index = 0;
var list=[];
if (this.state.listItems != undefined) {
list = this.state.listItems.map(function (item) {
return (
<ListItemComponent
key={index++}
item={item}
whenItemClicked={this.handleItemClick}
className={this.state.selectedItems.indexOf(item) != -1 ? "active" : ""}
/>);
}.bind(this));
} else {
list = this.props.listItems.map(function (item) {
return (
<ListItemComponent
key={index++}
item={item}
whenItemClicked={this.handleItemClick}
className={this.state.selectedItems.indexOf(item) != -1 ? "active" : ""}
/>);
}.bind(this));
}
return <div className="btn-group bootstrap-select form-control">
<DropDownButtonComponent
whenClicked={this.handleClick}
title={this.state.title}
/>
<ul className={"dropdown-menu inner dropdown-menu " + (this.state.open ? "show" : "") }>
{this.props.search? <li><input type="text" style={{margin:"auto", maxWidth:"96%"}} onChange={this.handleTextChange} placeholder="Search"/></li> :""}
<li className="disabled"><a>Select from below list {this.props.multiple ? <i title="clear all" style={{fontSize:"15px"}} onClick={this.clearSelected} className="text-danger fa fa-ban pull-right"></i>: ""}</a></li>
{list}
</ul>
</div>
}
});
Thanks in advance
When I'm sending state of the child ponent to its parent ponent, React is sending old state to the parent ponent.
I want to send the updated state on every click on ListItem which is properly working and calling the function handleItemClick.
But when I'm calling sendStateToParent
. It is passing old state of it. Suppose I have clicked on ITEM1
, it is sending empty array[]
. Next I have clicked on ITEM2
, it is sending array [ITEM1]
.
Here I'm actually creating a multiselect dropdown. which also can act as single select based on props it is getting.
import React from 'react';
import ListItemComponent from './ListItem.jsx';
import DropDownButtonComponent from './DropDownButton.jsx';
import DropDownStyle from '../../../../css/sass/drop-down.scss';
module.exports = React.createClass({
handleClick: function () {
this.setState({open: !this.state.open});
},
getInitialState: function () {
return {
open: false,
//listItems: this.props.listItems,
selectedItems:[],
title: this.props.dropdownTitle
}
},
handleItemClick: function (item) {
var selectedItems = [];
if(this.props.multiple == true){
selectedItems = this.state.selectedItems;
if(selectedItems.indexOf(item)==-1){
selectedItems.push(item);
}else{
selectedItems.splice(selectedItems.indexOf(item),1)
}
this.setState({
title: this.state.selectedItems.length+" selected",
selectedItems: selectedItems
});
} else{
selectedItems = [];
selectedItems.push(item);
this.setState({
title: item,
selectedItems: selectedItems,
open: false
});
}
this.sendStateToParent();
},
sendStateToParent: function(){
this.props.ifListChanged(this);
},
handleTextChange: function (event) {
var filteredItems = [];
this.props.listItems.map(function(item){
if(item.toLowerCase().search(event.target.value.toLowerCase()) != -1){
filteredItems.push(item);
}
},this);
this.setState({
listItems: filteredItems
});
},
clearSelected: function(){
this.setState({
title: this.props.dropdownTitle,
selectedItems: [],
});
},
render: function () {
var index = 0;
var list=[];
if (this.state.listItems != undefined) {
list = this.state.listItems.map(function (item) {
return (
<ListItemComponent
key={index++}
item={item}
whenItemClicked={this.handleItemClick}
className={this.state.selectedItems.indexOf(item) != -1 ? "active" : ""}
/>);
}.bind(this));
} else {
list = this.props.listItems.map(function (item) {
return (
<ListItemComponent
key={index++}
item={item}
whenItemClicked={this.handleItemClick}
className={this.state.selectedItems.indexOf(item) != -1 ? "active" : ""}
/>);
}.bind(this));
}
return <div className="btn-group bootstrap-select form-control">
<DropDownButtonComponent
whenClicked={this.handleClick}
title={this.state.title}
/>
<ul className={"dropdown-menu inner dropdown-menu " + (this.state.open ? "show" : "") }>
{this.props.search? <li><input type="text" style={{margin:"auto", maxWidth:"96%"}} onChange={this.handleTextChange} placeholder="Search"/></li> :""}
<li className="disabled"><a>Select from below list {this.props.multiple ? <i title="clear all" style={{fontSize:"15px"}} onClick={this.clearSelected} className="text-danger fa fa-ban pull-right"></i>: ""}</a></li>
{list}
</ul>
</div>
}
});
Thanks in advance
Share Improve this question edited Nov 19, 2017 at 23:57 Damjan Pavlica 34.1k10 gold badges75 silver badges78 bronze badges asked May 18, 2016 at 10:11 Akhil PAkhil P 1,6202 gold badges21 silver badges30 bronze badges1 Answer
Reset to default 6The reason parent gets the old value of selecteditems, is because setState()
is an asynchronous operation. See explanation here:
setState()
does not immediately mutatethis.state
but creates a pending state transition. Accessingthis.state
after calling this method can potentially return the existing value.
So in your code, you send a request to update state, and before the new state is processed, you call the method in the parent, to inform parent about state, which still has the old items.
Fix 1: send current state to parent.
To get the item to send the current state, you could use the callback that setState()
provides. Explained also in react pages:
The second (optional) parameter is a callback function that will be executed once
setState
is pleted and the ponent is re-rendered.
This ensures that the call to parent is made only after setState()
is finished. Something like this:
this.setState(
{
title: item,
selectedItems: selectedItems,
open: false
},
this.sendStateToParent
);
Fix 2(optional but remended): move selecteditems state to parent.
If your parent needs to know about selecteditems, I would advise not to put these in state of the list. The only thing your ponent does with the selecteditems is to send them to the parent, every time an item is clicked.
Instead, it is better to:
- put selectedItems in state of the parent
- from the parent, pass selectedItems as props to the ponent
- move the
handleItemClick
logic to the parent - inside the parent, you update the list of selectedItems, and set state (of the parent)
- triggering a re-render of the list, with the new selectedItems as props
本文标签: javascriptReact is sending old state to its parentStack Overflow
版权声明:本文标题:javascript - React is sending old state to its parent - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742027715a2415861.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论