Избегайте повторного использования компонента при обновлении карты в useState

#javascript #reactjs #react-hooks

#javascript #reactjs #реагирующие хуки

Вопрос:

Как мне заполнить Map в useState, не вызывая повторного использования компонента React?

const [myMap, setMyMap] = useState(new Map());

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

 const insertToMap = (myMap, setMyMap, k, v) => {
myMap[k] = v;
  setMyMap(myMap);
}
 

или

 const insertToMap = (myMap, setMyMap, k, v) => {
myMap[k] = v;
  setMyMap(myMap.set(k, v));
}
 

Как мне заполнить карту, не вызывая повторного рендеринга?

Комментарии:

1. Как используется карта? Кажется немного странным иметь состояние, которое не влияет на рендеринг

2. Хороший довод. Ключи на карте являются идентификаторами элементов checkbox, а значения являются логическими (если они отмечены или нет). Итак, я хочу checked , чтобы -prop каждого флажка отображался правильно в соответствии с картой при повторном рендеринге (css зависит от статуса checked). Если в этом есть смысл. Может быть, мне следует заполнить карту за один раз?

3. Если значения карты соответствуют тому, что отображается, то не должно ли изменение значения приводить к повторному отображению? Звучит очень странно, что вы хотели бы избежать повторного рендеринга, когда изменяется то, что звучит как важная переменная с отслеживанием состояния (которая соответствует тому, что отображается)

4. Верно. Я немного смущен настройкой, я думаю. Моей первой мыслью было заполнить карту без запуска повторного рендеринга, а затем запускать повторный рендеринг только при нажатии флажка и далее

Ответ №1:

Если карта вообще не учитывается при рендеринге, вместо этого вы можете изменить ее — и в таком случае было бы разумнее использовать ссылку, чем состояние:

 const myMapRef = useRef(new Map());
// reference myMapRef.current to get to the map
 

Но также обратите внимание, что если вы хотите использовать карту в качестве карты, вы должны использовать методы Map .set , .get , и .has :

 const insertToMap = (myMap, k, v) => {
  myMap.set(k, v);
};
 

Если вы хотите использовать скобки для хранения значений, вы почти наверняка должны использовать вместо этого обычный объект, например

 const myObjRef = useRef({});
myObjRef[k] = v;
 

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

Я хочу, чтобы флажок каждого флажка отображался правильно в соответствии с картой при повторном отображении

похоже, это действительно должно быть с учетом состояния — вы почти наверняка должны хотеть, чтобы изменение значения приводило к тому, что флажок немедленно устанавливался или снимался (через изменение состояния и результирующий повторный рендеринг).

Хорошо, чтобы значения с сохранением состояния можно было легко клонировать, чтобы установка их состояния (без изменения текущего состояния объекта) не была слишком утомительной. Рассмотрите возможность использования объекта вместо карты и:

 const [checkboxes, setCheckboxes] = useState({});
const insert = (k, v) => {
  setCheckboxes({ ...checkboxes, [k]: v });
};
 

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

 setCheckboxes(checkboxes => ({ ...checkboxes, [k]: v }));
 

Моей первой мыслью было заполнить карту без запуска повторного отображения

Если все начальные настройки выполняются синхронно, беспокоиться не о чем. Вы также можете заполнить его перед вызовом этого компонента и передать заполненный объект в качестве реквизита.