Состояние обновления, которое зависит от другого вычисленного состояния в React-Hooks - PullRequest
0 голосов
/ 25 октября 2019

Я хочу обновить состояние (данные), которое зависит от другого вычисляемого состояния (сервер)

 setServer(prevTweets =>
          [...json, ...prevTweets].filter(
            (e, i, arr) => i === arr.findIndex(t => t.tweetId === e.tweetId)
          )
  )

Приведенные выше данные будут использоваться для установки состояния ниже (данные):

let totalPositive = 0;
        let totalNegative = 0;
        let totalNeutral = 0;
        server.forEach(tweet => {
          if(tweet.sentiment >0) totalPositive++;
          if(tweet.sentiment < 0) totalNegative++;
          if(tweet.sentiment ===0) totalNeutral++;
        })

setData([
       { name: 'Positive', value: totalPositive },
       { name: 'Negative', value: totalNegative },
       { name: 'Neutral', value: totalNeutral },
 ])

Поскольку он асинхронный, операция setData всегда запаздывает. Я знаю, что могу использовать useEffect, но, по-видимому, оно создаст бесконечный цикл, и в этом случае неправильно его использовать.

1 Ответ

0 голосов
/ 25 октября 2019

Если вы установите новые данные до того, как настроите сервер, вы пропустите один рендер:

//still defaults to server so if you do't pass anything it;s still the same
const setNewData = (newServer = server) => {
  const [
    totalPositive,
    totalNegative,
    totalNeutral,
  ] = newServer.reduce(
    ([pos, neg, neu], { sentiment }) =>
      sentiment > 0
        ? [pos + 1, neg, neu]
        : sentiment < 0
        ? [pos, neg + 1, neu]
        : [pos, neg, neu + 1],
    [0, 0, 0]
  );

  setData([
    { name: 'Positive', value: totalPositive },
    { name: 'Negative', value: totalNegative },
    { name: 'Neutral', value: totalNeutral },
  ]);
};

setServer(prevTweets => {
  const newServer = uniqueByTweetId([
    ...json,
    ...prevTweets,
  ]);
  setNewData(newServer);
  return newServer;
});

Не имеет отношения к вопросу, но может быть важно то, что способ получения уникальных значений может быть улучшен. Вы можете получить уникальные значения за один проход без многократного вызова индекса поиска:

const uniqueBy = getter => arr => {
  const items = new Map();
  return arr.filter(item => {
    const key = getter(item);
    const ret = items.get(key);
    items.set(key,true);
    return !ret;
  });
};
const data = [
  { id: 1 },
  { id: 2 },
  { id: 3 },
  { id: 4 },
  { id: 5 },
  { id: 1 },
  { id: 7 },
  { id: 1 },
  { id: 7 },
  { id: 8 },
  { id: 1 },
];
const uniqueById = uniqueBy(i => i.id);
console.log(uniqueById(data));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...