Как установить состояние в al oop? - PullRequest
2 голосов
/ 16 июня 2020

Я хочу l oop через массив и вызывать функцию для каждого элемента, которая выполняет setState. Я пробовал следующий код:

const approveOrder = uniqueId => {
    if (approvedList.indexOf(uniqueId) < 0) {
        setApprovedList(approvedList.concat(uniqueId));
    }
};

const approveAllOrders = data => {
    data.forEach(dataItem => {
        approveOrder(dataItem.unique_id);
    });
};

Но после вышеупомянутой функции approveAllOrders мой список approvedList содержит только один элемент, который является последним элементом моих данных, которые я передал функции. Я знаю, что setState не мгновенный, поэтому это происходит. Итак, что я могу сделать, чтобы мой код заработал?

Ответы [ 3 ]

2 голосов
/ 16 июня 2020

Вы должны использовать обновление функционального состояния, чтобы несколько обновлений в очереди правильно обновляли из предыдущего состояния.

const approveOrder = uniqueId => {
  if (approvedList.indexOf(uniqueId) < 0) {
    setApprovedList(approvedList => approvedList.concat(uniqueId));
  }
};

В качестве альтернативы вы можете фильтровать / отображать свои данные по идентификаторам, не содержащимся в текущее состояние и обновить состояние один раз.

const approveAllOrders = data => {
    const newDataIds = data.filter(dataItem => {
        return approvedList.indexOf(dataItem.unique_id) < 0;
    }).map(({ unique_id }) => unique_id);
    setApprovedList(approvedList => [...approvedList, newDataIds]);
};

или

const approveAllOrders = data => {
    const newDataIds = data.filter(dataItem => {
        return !approvedList.includes(dataItem.unique_id);
    }).map(({ unique_id }) => unique_id);
    setApprovedList(approvedList => [...approvedList, newDataIds]);
};
1 голос
/ 16 июня 2020

Вы можете сначала создать список всех заказов, а затем обновить состояние. Для этого не обязательно иметь 2 функции.

const approveAllOrders = data => {
    const orders = [];

    data.forEach(dataItem => {
       if (approvedList.indexOf(dataItem.unique_id) < 0) {
          orders.push(dataItem);
       }
    });

    setApprovedList([...approvedList, ...orders]);
};
0 голосов
/ 16 июня 2020

здесь также можно использовать сокращение.

const res = data.reduce( (res, dataItem) => {
   if(!res.includes(dataItem.unique_id)) {
       res.push(dataItem.unique_id)
   }
   return res
})

setApprovedList(res)

...