предотвращать дублирование при объединении избыточного массива объектов с массивом setState - PullRequest
0 голосов
/ 10 июля 2019

Прежде всего один общий вопрос: как связать массив setState с массивом redux?В моей реализации есть настроенный список, основанный на массиве объектов setState.Теперь у меня есть список местоположений, который основан на избыточном массиве объектов.Теперь я добавляю один элемент из списка местоположений в настроенный список, используя concat и сохраняя данные.Он успешно сохранен, но в объединенном списке он отображает 3 элемента (этот элемент редуцирует массив 2 раза).

Но я проверил в консоли, хотя он показывает правильный результат (2 элемента), но почему он отображает 3 элемента (редукция 2 раза).

Код компонента: (метод 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
              );
         }


}

Я добавляю токовый выход, который показывает 3 результата, но он должен показывать 2 результата.Как это предотвратить. Пожалуйста, помогите мне в этом. enter image description here

1 Ответ

0 голосов
/ 10 июля 2019

ОБНОВЛЕНИЕ № 1:

mergeLocationData(){
  let mergedList = [];    
  // you either have to setup initial state for conLocations in your reducer to `undefined` or to `null`. 
  if(this.props.conLocations !== undefined && this.state.configuredList !== null){
    const { configuredList } = this.state;
    const { conLocations } = this.props;
    mergedList = configuredList;

    this.props.conLocations.forEach(location => {
      const locationAdded = mergedList.find(_location => _location.mruCode === location.mruCode);
      if(!locationAdded){
        mergedList.push(location)
      }
    });
  }
    // instead of setting state, return the mergedList
    return mergedList; //[ always an array of elements ]
}

И затем, при методе рендеринга: вместо получения списка из состояния, мы просто вызываем функцию.

<thead>
  {
    this.mergeLocationData().map((locc,index)=> (
      <tr key={index}>
        <th>
          <b>{locc.mruCode} - {_labels[locc.division]} - {locc.country}</b>
        </th>
        <th className="text-right">
          <img
            alt="DeleteIcon"
            onClick={()=>{this.removeConfigLocation(index)}}
            className="deleteIconStyle"
            src="img/delete_large_active.png" />
        </th>
      </tr>
    )
  }
</thead>

В коде нет ничего плохого, я полагаю, что он работает правильно, но логика неверна, вы рендерите оба массива в вашем рендере, вы не используете функцию getLocationData в своих программах. компонент, даже если concat не решит проблему.

Вы можете сделать следующие шаги, чтобы исправить логику. - Исправить логику getLocationData:

mergeLocationData(){      
  // you either have to setup initial state for conLocations in your reducer to `undefined` or to `null`. 
  if(this.props.conLocations !== undefined && this.state.configuredList !== null){
    const { configuredList } = this.state;
    const { conLocations } = this.props;
    let mergedList = configuredList;

    this.props.conLocations.forEach(location => {
      const locationAdded = mergedList.find(_location => _location.mruCode === location.mruCode);
    });

    this.setState({
        mergedList
    });
  }
}
  • Используйте функцию в качестве обратного вызова к вашему запросу на выборку, предположительно в componentDidMount после правильной загрузки данных.

  • Рендеринг нового Array из mergedList, который должен быть в вашем штате к настоящему времени, и не забудьте добавить mergedList: [] в ваше состояние. По сути, вам нужно заменить две карты, которые отображают элементы местоположения в вашем рендере, на это.

    <thead>
      {
        this.state.mergedList.map((locc,index)=> (
          <tr key={index}>
            <th>
              <b>{locc.mruCode} - {_labels[locc.division]} - {locc.country}</b>
            </th>
            <th className="text-right">
              <img
                alt="DeleteIcon"
                onClick={()=>{this.removeConfigLocation(index)}}
                className="deleteIconStyle"
                src="img/delete_large_active.png" />
            </th>
          </tr>
        )
      }
    </thead>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...