В чем разница между деструктуризацией и просто использованием свойств в React

У меня есть некоторые проблемы с кодом React. Внутри моего App.jsx я написал логику с деструктуризацией объекта, полученной из тега jsx, и без него:


<input
   name = "fName"
   placeholder = "First Name"
   onChange = {handleChangeEvent}
   value = {fullName.fName}
/>
<input
   name = "lName"
   placeholder = "Last Name"
   onChange = {handleChangeEvent}
   value = {fullName.lName}
/>

Вот код с способом деструктуризации:


function handleChangeEvent(event) {
    const { name, value } = event.target;

    setFullName((preValue) => {
      if (name === "fName") {
        return {
          fName: value,
          lName: preValue.lName,
        };
      } else if (name === "lName") {
        return {
          fName: preValue.fName,
          lName: value,
        };
      }
    });
  }

Хотя это код без деструктуризации


function handleChangeEvent(event) {
    setFullName((preValue) => {
      if (event.target.name === "fName") {
        return {
          fName: event.target.value,
          lName: preValue.lName,
        };
      } else if (event.target.name === "lName") {
        return {
          fName: preValue.fName,
          lName: event.target.value,
        };
      }
    });
  }

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

TypeError
Cannot read properties of null (reading 'name')
eval
/src/components/App.jsx:11:23
   8 | 
   9 | function handleChangeEvent(event) {
  10 |   setFullName((preValue) => {
> 11 |     if (event.target.name === "fName") {
     |                     ^
  12 |       return {
  13 |         fName: event.target.value,
  14 |         lName: preValue.lName,


Я ожидаю, что это сработает, даже если я не использую деструктуризацию.

В первом примере значения name и value копируются до вызова setFullName. Во втором примере осуществляется доступ к объекту event. Вы получите другое поведение, если объект будет изменен.

jabaa 07.08.2024 17:55

@jabaa …и на самом деле объект event модифицируется, поскольку он перемещается вверх по дереву DOM, пока не достигнет вершины; перед повторной визуализацией компонента и вызовом функции обновления состояния. Я немного удивлен, что event.target становится null (а не просто event.currentTarget, который меняется во время всплытия), но это также может быть специфично для синтетических событий React.

Bergi 07.08.2024 18:00

Я думаю, что ваша проблема связана с масштабом. Просто избавьтесь от объявления функции setFullName и сохраните тело функции.

hippoman 07.08.2024 20:19

@hippoman Это не объявление функции. Это вызов функции.

jabaa 07.08.2024 20:53

Кажется, вы используете более старую версию React, и событие было обнулено и возвращено в пул событий. Я считаю, что это изменилось в React 17. Вызовите event.persist() во второй реализации, если вы хотите, чтобы объект события передавался до тех пор, пока не будет обработано обновление состояния React.

Drew Reese 10.08.2024 09:21
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
5
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это не имеет ничего общего с деструктуризацией. Это важно только при доступе к объекту.

В первом фрагменте значения name и value копируются до вызова setFullName. Во втором примере доступ к объекту event осуществляется после вызова setFullName. Объект является изменяемым, и вы получите другое поведение, если объект будет изменен до того, как будут прочитаны его значения.

const event = {
  target: {
    name: 'Name',
    value: 123
  }
}

function f1(event) {
  const { name, value } = event.target;
  g(() => { console.info(name, value); });
}

function f2(event) {
  g(() => { console.info(event.target.name, event.target.value); });
}

function g(f) {
  setTimeout(f, 10);
}

f1(event);
f2(event);
event.target.name = 'New name';
event.target.value = 321;

Пример:

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

const event = {
  target: {
    name: 'Name',
    value: 123
  }
}

function f1(event) {
  g(() => { 
    const { name, value } = event.target; 
    console.info(name, value);
  });
}

function f2(event) {
  const name = event.target.name;
  const value = event.target.value;
  g(() => { console.info(name, value); });
}

function g(f) {
  setTimeout(f, 10);
}

f1(event);
f2(event);
event.target.name = 'New name';
event.target.value = 321;

Я понимаю ваш пример. Однако я хочу спросить больше, почему в моем коде появляется ошибка Cannot read properties of null (reading 'name'), хотя я продолжаю вводить значение во входной тег

Thang Thang 08.08.2024 02:36

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

jabaa 10.08.2024 10:15

@ThangThang Дело в том, что если вы получили ответ на свой вопрос, вы можете принять его (для этого есть кнопка) или нет. Если у вас есть дополнительный вопрос, который слишком велик и не помещается в текущий вопрос, просто задайте еще один вопрос.

Ted Lyngmo 11.08.2024 04:46

Другие вопросы по теме