Akh*_*l P 5 javascript state reactjs
当我将子组件的状态发送到其父组件时,React 将旧状态发送到父组件。
我想在每次单击 ListItem 时发送更新的状态,该状态正常工作并调用函数 handleItemClick。
但是当我打电话时sendStateToParent。它正在过去它的旧状态。假设我点击了ITEM1,它正在发送空数组[]。接下来我点击了ITEM2,它正在发送数组[ITEM1]。
在这里,我实际上是在创建一个多选下拉列表。它也可以作为基于它获得的道具的单一选择。
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>
}
});
Run Code Online (Sandbox Code Playgroud)
提前致谢
parent 获取 selecteditems 的旧值的原因是因为setState()是异步操作。请参阅此处的说明:
setState()不会立即变异,this.state而是创建一个挂起的状态转换。this.state调用此方法后访问可能会返回现有值。
因此,在您的代码中,您发送更新状态的请求,并在处理新状态之前,调用父级中的方法,以通知父级有关状态的信息,该状态仍然具有旧项。
修复 1:将当前状态发送给父级。
要让项目发送当前状态,您可以使用setState()提供的回调。也在反应页面中解释:
第二个(可选)参数是一个回调函数,一旦
setState完成并重新渲染组件就会执行。
这确保只有在setState()完成后才能调用 parent 。像这样的东西:
this.setState(
{
title: item,
selectedItems: selectedItems,
open: false
},
this.sendStateToParent
);
Run Code Online (Sandbox Code Playgroud)
修复 2(可选但推荐):将 selecteditems 状态移动到父项。
如果您的父母需要了解选定的项目,我建议不要将这些放在列表中。您的组件对 selecteditems 所做的唯一事情就是每次单击一个项目时将它们发送到父级。
相反,最好是:
handleItemClick逻辑移至父级