【发布时间】:2019-11-19 16:45:30
【问题描述】:
首先一个普遍的问题是如何连接 setState 数组和 redux 数组?在我的实现中,有一个基于 setState 对象数组的配置列表。现在,我有一个基于 redux 对象数组的位置列表。现在我正在使用 concat 将位置列表中的一项添加到配置列表并保存数据。它已成功保存,但在合并列表中显示 3 个项目(即 redux 数组项目 2 次)。
但是,我检查了控制台,虽然它显示了正确的结果(2 项),但为什么它显示 3 项(redux 项 2 次)。
组件代码:(getLocationData 方法,我做了连接部分并使用回调引用在其他组件中调用该方法并且工作正常)
export class NewLocationPanel extends React.Component{
constructor(props){
super(props);
this.state={
open:false,
configuredList:[],
retrievedList:[]
};
this.configLocation = this.configLocation.bind(this);
this.togglePanel = this.togglePanel.bind(this);
this.handleClick = this.handleClick.bind(this);
this.allLocations = this.allLocations.bind(this);
this.clearall = this.clearall.bind(this);
this.getLocationData = this.getLocationData.bind(this);
this.handleRemove = this.handleRemove.bind(this);
this.removeConfigLocation = this.removeConfigLocation.bind(this);
this.mergedLocation = this.mergedLocation.bind(this);
}
togglePanel (e){
this.setState({open : !this.state.open});
}
handleRemove(mruCode){
this.props.removeLocation(mruCode)
}
handleClick (mruCode){
this.props.addLocation(mruCode)
}
allLocations (){
this.props.addAllLocation()
}
clearall (){
this.props.removeAllLocation()
}
componentDidMount() {
this.props.loadData();
if(this.props.locationData !=null && this.props.locationData!= undefined){
this.configLocation(this.props.locationData);
}
}
componentDidUpdate(prevProps,prevState){
if ((prevProps.jobId != this.props.jobId || prevProps.locationData != this.props.locationData) && this.props.locationData != null && this.props.locationData != undefined) {
this.configLocation(this.props.locationData);
this.mergedLocation();
}
}
configLocation(locationData){
let configuredList =[];
if(locationData.locations.locationDetails != null && locationData.locations.locationDetails !=undefined ){
locationData.locations.locationDetails.map(item=>{
let listitem ={...item};
configuredList.push(listitem);
});
}
this.setState({configuredList},()=>{
console.log(this.state.configuredList);
});
}
removeConfigLocation(index){
this.setState({
configuredList:this.props.locationData.locations.locationDetails.filter((_,i)=>i!==index)
},()=>{
console.log(this.state.configuredList);
});
}
mergedLocation(){
if(this.props.conLocations != null && this.state.configuredList !=null){
const{configuredList} = this.state;
let retrievedList = configuredList;
this.props.conLocations.forEach(loct => {
const locationAdded = retrievedList.find(_loct=>loct.mruCode=== loct.mruCode)
});
this.setState({
retrievedList},()=>{
console.log(this.state.retrievedList);
});
}
}
getLocationData(){
let saveableLocationlist = [];
if(this.state.retrievedList != null){
saveableLocationlist = retrievedList;
}
const locationData = {
locationDetails : saveableLocationlist
}
return locationData;
}
render(){
//const{configuredList} = this.state;
const _labels = store.getLabels();
let collapsedToggle = this.props.open ? 'collapsed' : ''
return(
<div className="panel panel-default">
<div className="panel-heading" onClick={(e)=>this.togglePanel(e)}>
<div className="row">
<div className="col-xs-12 col-sm-8 col-md-6 col-lg-6 panelHeadingLabel">
<span>{this.props.title}</span>
</div>
<div className="pull-right">
<span className="defaultHeaderTextColor">{this.state.configuredList.map((loc,index)=><span key={index}>{loc.mruCode} - {_labels[loc.division]} - {loc.country}</span>)}
<span onClick={(e)=>this.togglePanel(e)} className={this.state.open ? "collapse-chevronn" : "collapse-chevron"} aria-hidden="true"></span>
</span>
</div>
</div>
</div>
{this.state.open?(
<div className="panel-body">
<div className="row grid-divider">
<div className="col-sm-6">
<div className="col-padding"><div className="pos-div"><h3>Locations List</h3><button style={{ display: this.props.location.length === this.props.conLocations.length ? "none" : "block" }} className="allLargeBtn" onClick={()=>{this.allLocations()}}>Add all locations</button></div><hr/>
{this.props.location.map((item,index)=>(
<div key={index}><div><b>{item.mruCode} - {_labels[item.division]} - {item.country}</b>{!this.props.conLocations.find(item2 => item.mruCode === item2.mruCode)&&(<div className="pull-right jd"><button style={{ display: this.state.configuredList.find(item3=> item.mruCode===item3.mruCode) ? "none" : "block" }} className="call-to-action" onClick={()=>{this.handleClick(item.mruCode)}}>Add Location</button></div>)}<hr/></div></div>))}
</div>
</div>
<div className="col-sm-6">
<div className="col-padding">
<div className="pos-div"><h3>Configured Location</h3><button className="allLargeBtn" onClick={()=>this.clearall()}>Remove all location</button></div><hr/>
<div><table className="table"><tbody>{this.state.retrievedList.map((locc,index)=><tr key={index}><td><b>{locc.mruCode} - {_labels[locc.division]} - {locc.country}</b></td><td className="text-right"><img alt="DeleteIcon" onClick={()=>{this.removeConfigLocation(index)}} className="deleteIconStyle" src="img/delete_large_active.png" /></td></tr>)}
</tbody></table></div>
</div>
</div>
</div>
</div>):null}
</div>
);
}
}
const mapStateToProps = state =>{
return{
location:state.locationRed.location,
conLocations:state.locationRed.conLocations
};
};
const mapDispatchToProps = (dispatch) => {
return{
loadData:()=>{dispatch(loadData())},
addLocation:(mruCode)=>{dispatch(addLocation(mruCode))},
addAllLocation:() =>{dispatch(addAllLocation())},
removeLocation: (mruCode)=>{dispatch(removeLocation(mruCode))},
removeAllLocation: () =>{dispatch(removeAllLocation())}
}
}
export default connect(mapStateToProps,mapDispatchToProps,null,{withRef:true})(NewLocationPanel);
工作组件(我调用 getLocationData 来保存工作的更新值...它正在正确保存详细信息)
import React from 'react';
import ReactDOM from 'react-dom';
import LocationPanel from '../panels/NewLocationPanel';
class JobsPanelComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
jobDetailJson: this.props.jobDetailJson
};
this.setLocationPanelRef = cRef =>{this.locationPanel = cRef;};
}
componentWillUnmount() {
this.clearStates();
this.clearRefs();
this.clearBindings();
}
clearStates() {
this.state.jobDetailJson = null;
}
clearRefs(){
this.locationPanel = null;
}
clearBindings(){
this.setLocationPanelRef = null;
}
componentWillMount() {
this.state.jobDetailJson = this.props.jobDetailJson;
}
componentWillReceiveProps(nextProps) {
this.state.jobDetailJson = nextProps.jobDetailJson;
}
saveJobData(jobData){
var locationData = null;
if(some conditions){
locationData = this.locationPanel.getWrappedInstance().getLocationData();
}
//more other lines not related to my mine
}
render(){
var locationDataJson= null;
if(this.state.jobDetailJson != null){
locationDataJson =this.state.jobDetailJson;
}
return(<div className="panel-group" id="jobsPanelGroup">
<LocationPanel ref={this.setLocationPanelRef} locationData ={locationDataJson} jobDetailJson={this.state.jobDetailJson} versionId={versionId} jobName={jobName} jobId={jobId} isForViewOnly={this.props.isForViewOnly} parentJobId={this.props.parentJobId} title="Location"/>
//More coded lines for other things not related to my part
);
}
}
【问题讨论】:
-
将console.log 放入getLocationData 以获取配置列表和conLocations。如果有帮助,请告诉我,以便我写一个答案。
-
是的,configuredList 是第一个数据值,如图片。对于添加单个项目后的 conLocations,它显示第二个数据值。是的,我以不同的方式渲染了两个数组。
标签: javascript arrays reactjs redux