Фильтровать массив объектов в новые массивы - PullRequest
2 голосов
/ 02 мая 2019

В React у меня есть:

    state = {
     Producers: [], 
     France: [],
     Spain: [],
     Germany: [],
     Portugal: [],
     Greece: [],
     Austria: [],
     isLoading: false
     };

Массив производителей:

     {
    "_id" : ObjectId("5cc0bf1815cc7a2225edab0b"),
    "Code" : "FPG-BCH14",
    "URL" : "/jSQcl",
    "Just_In" : "",
    "Country" : "France",
    "Region" : "Burgundy"
},
{
    "_id" : ObjectId("5cc0bf1815cc7a2225edab0c"),
    "Code" : "FPG-CHA17",
    "URL" : "/XPxx",
    "Just_In" : "",
    "Country" : "France",
    "Region" : "Burgundy"  
},
{
    "_id" : ObjectId("5cc0bf1815cc7a2225edab0d"),
    "Code" : "FPG-BPN16",
    "Just_In" : "",
    "Country" : "France",
    "Region" : "Burgundy"

},

{
    "_id" : ObjectId("5cc0bf1815cc7a2225edab0e"),
    "Code" : "PAP-VIN17",
    "Country" : "Portugal",
    "Region" : "Vinho Verde",
    "Subregion" : "Lima"

}

Сейчас у меня есть все объекты в state.Producers, и я хочу поместить любой объект, имеющий значениеstate.Producers.Country === "France" (и так далее для всех стран).

Вот как я устанавливаю состояние:

    loadProducers = () => {

     API.getProducers()
     .then(res => 
     this.setState({Producers: res.data})
     )
     .catch(err => console.log(err));
       }

, поэтому я подумал, что мне нужно другое утверждение .then после установкиукажите для производителей, а затем .filter для каждой страны, но я не могу заставить его работать.

Ответы [ 3 ]

0 голосов
/ 02 мая 2019

Вы можете сделать это так.

loadProducers = () => {
 API.getProducers()
  .then(({ data }) =>
    // Here we reduce all the results with respect to the country associated with
    updatedState = data.reduce((res, obj) => {
     if (!res[obj.Country]) {
       res[obj.Country] = [];
     }
     return { ...res, [obj.Country]: [...res[obj.Country], obj] }
    }, {});

    // Push all the data into Producers provided that you need it here. else you can ignore this line :)
    updatedState.Producers = data;

    //Finally update the state 
    this.setState(updatedState);
  ).catch(({ response }) => console.log(response));
}

Надеюсь, это поможет.

0 голосов
/ 02 мая 2019

React.Component#setState() ничего не возвращает, поэтому Promise#then() будет передано неопределенное значение для его обратного вызова. Чтобы избежать этого, вместо этого передайте обратный вызов setState(), чтобы он запускался после обновления состояния, , но вы должны использовать правильный метод и использовать жизненный цикл React.Component#componentDidUpdate(). Существует множество причин, по которым вам следует использовать жизненный цикл, в том числе для того, чтобы вы могли легко изменить источник источника данных, не меняя при этом, как происходит состояние, жизненный цикл практически не требует обслуживания, и он всегда будет работать, когда Обновление компонента означает, что у вас не будет проблем с синхронизацией на основе гоночных асинхронных условий.

this.componentDidUpdate = function componentDidUpdate(
  previousProps,
  previousState
) {
  // wrap it in a comparison so that you don't infinitely loop
  if (//compare producers to previous producers here) {
    // they have changed, update state, use updater to prevent timing problems
    this.setState(state => {
      // keep changing data in sync
      // this also allows you to fetch changing data over time
      const update = {...state};
      state.producers.forEach(producer => {
        // safely initialize
        update[producer.Country] = update[producer.Country] || [];
        if (!update[producer.country].find(producer) {
          // push onto
          update[producer.Country].push(producer);
        }
      });
      return update;
    })
  }
}

Это гарантирует безопасное выполнение обновления состояния в классе, и ваши задачи (выборки) и производные (производные структуры) будут разделены и просты в обслуживании.

0 голосов
/ 02 мая 2019

Если у вас res.data есть структура [{Country: string}, {Country: string}...], вы можете создать объект updatedState и вставить в него элементы.

Примерно так:

const loadProducers = () => {
    API.getProducers()
    .then(res => {
        const updatedState = {
            Producers: [], 
            France: [],
            Spain: [],
            Germany: [],
            Portugal: [],
            Greece: [],
            Austria: []
        };
        res.data.forEach((item) => {
            updatedState[item.Country].push(item);
        })
        // This line if you also need everything inside Producers
        updatedState.Producers = res.data;

        this.setState(updatedState);
    })
    .catch(err => console.log(err));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...