Как добавить элемент в неизменяемый массив в React setState в Typescript? - PullRequest
0 голосов
/ 17 февраля 2020

Я хочу использовать неизменный массив для обработки состояния. И добавить элемент в этот список.

interface MainState {
  list: readonly []; // define immutable array
}

const Component: React.FC = () => {
  // by default use the immutable array with type
  const [classes, setClasses] = useState({ list: [] } as MainState);

  useEffect(() => {
    if (data) {
      data.forEach((thing) => {
        setClasses(prevState => {
          //
          // Call signature return types '{ list: never[]; }' and 'MainState' are incompatible.
          // The types of 'list.length' are incompatible between these types.
          // Type 'number' is not assignable to type '0'.  TS2345
          //
          const list = prevState.list.concat(thing);
          return { list };
        });
      });
    }
  });
// ...

}

Я, хотя с использованием concat будет работать, так как он возвращает новый массив .

Ответы [ 2 ]

2 голосов
/ 17 февраля 2020

Самый простой и приемлемый способ сделать это:

const list = [...prevState.list, thing];
0 голосов
/ 17 февраля 2020

Из do c, который вы указали:

Метод concat () используется для объединения двух или более массивов

Так вам нужно передать массив, а не элемент этой функции, я полагаю, это будет работать:

const list = prevState.list.concat([thing]);

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

    if (data) {
        setClasses(prevState => {
          const list = prevState.list.concat(data);
          // or list = [...prevState.list, ...data];
          return { list };
        });
    }

Также я думаю, что вы пропустили тип массива в вас MainState, хотя бы обновите его с типом any, вот полный пример для number type:

interface MainState {
  list: readonly number[];
}

const data = [1, 2, 3]

const Component: React.FC = () => {

  const [classes, setClasses] = useState({ list: [] } as MainState);

  useEffect(() => {
    if (data) {
      setClasses(prevState => ({ list: [...prevState.list, ...data]}));
    }
  });

  return <div>{classes}</div>
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...