当我将子组件的状态发送到其父组件时,React会将旧状态发送到父组件。
我想在ListItem的每次单击上发送更新状态,该列表正常工作并调用函数handleItemClick。
但是当我打电话时sendStateToParent。它正在过去。假设我单击了ITEM1,它正在发送空数组[]。接下来,我单击ITEM2,它正在发送数组[ITEM1]。
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> } });
提前致谢
父级获得selecteditems的旧值的原因是因为它setState()是一个异步操作。在这里查看说明:
setState()
setState()不会立即变异,this.state但会创建待处理的状态转换。this.state调用此方法后进行访问可能会返回现有值。
this.state
因此,在您的代码中,您发送了一个更新状态的请求,并 在处理新状态之前 ,在父级中调用该方法,以通知父级状态,该状态仍然具有旧项。
修复1: 将当前状态发送给父级。 要使该项目发送当前状态,可以使用setState()提供的回调。在反应页面中也有解释:
第二个(可选)参数是一个回调函数,该函数将在setState完成并重新渲染组件后执行。
setState
这样可以确保仅在setState()完成后才调用父对象。像这样:
this.setState( { title: item, selectedItems: selectedItems, open: false }, this.sendStateToParent );
修复2 (可选,但建议):将selecteditems状态移到父级。 如果您的父母需要了解所选项目,我建议不要将其置于列表状态。您的组件对所选项目所做的唯一一件事就是,每次单击某个项目时,将其发送给父项。 相反,最好是:
handleItemClick