event.stopPropagation, кажется, препятствует использованию и обновлению useState - PullRequest
1 голос
/ 13 мая 2019

У меня есть несколько строк в списке, которые являются панелями расширения Material-UI. Строки отображаются из массива rowData. Каждый ряд может расширяться. Каждая строка также имеет значок удаления, который при нажатии должен удалить строку.

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

<DeleteIcon
  id={key}
  onClick={event => {
     onDelete(event, key); //key is specific row id
  }}
  className={classes.icons}
/>

const onDelete = (event, key) => {
    let newCategories = categories;
    delete newCategories[key];
    setCategories(newCategories);
};

Сначала я попытался установить панель в false, чтобы закрыть ее:

const [expanded, setExpanded] = useState(false);
...
const onDelete = (event, key) => {
  setExpanded(false)
...

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

Итак, затем я попытался использовать event.stopPropagation:

const onDelete = (event, key) => {
    event.stopPropagation();
    let newCategories = categories;
    delete newCategories[key];
    setCategories(newCategories);
  };

Но теперь строка не удаляется в представлении (это происходит в консоли). Я предполагаю, что event.stopPropagation не позволяет моему состоянию (setCategories) форсировать повторный рендеринг, как обычно делают изменения внутри хука useState. Однако, если я нажимаю на значок удаления, то после того, как я щелкаю по строке, чтобы развернуть панель, состояние обновляется, и строка удаляется. Итак, я вынул event.stopPropagation и теперь у меня есть это:

const onDelete = (event, key) => {
    let newCategories = categories;
    delete newCategories[key];
    setCategories(newCategories);
    setTimeout(() => {
      setExpanded(false);
    }, 100);
};

Это работает и добавляет аккуратный небольшой эффект следующей панели, очень кратко открывающейся перед удалением строки, но я хотел бы иметь лучшее представление о том, что происходит с использованием event.stopPropagation и обновления состояния с использованием хуков useState.

EDIT:

Ссылка на коды и окна: https://codesandbox.io/embed/61j19k1q13

Я оставил event.stopPropagation () в функции onDelete () для проверки. Нажмите на значок удаления и смотрите, что ничего не происходит. Затем нажмите на строку, чтобы развернуть панель и заметить, что она исчезает. Спасибо!

1 Ответ

2 голосов
/ 14 мая 2019

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

Изменить это:

const onDelete = (event, key) => {
    let newCategories = categories; // this line is the problem
    delete newCategories[key];
    setCategories(newCategories);
};

вместо:

const onDelete = (event, key) => {
    // create a new object rather than mutating existing object
    let newCategories = { ...categories }; 
    delete newCategories[key];
    setCategories(newCategories);
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...