Повторно отрисовать входной компонент, не теряя фокус при повторном рендеринге

Я представляю два разных способа визуализации компонента ввода;

Пример 1

function myComponent(){                 
const [st, setSt] = useState('');       
                                        
return <div>                            
{Math.random()}                         
<input value = {st}                      
  onChange = {e=>setSt(e.target.value)/>  
</div> 

Например. 2

 function StateHelper() {
  const [st, setSt] = useState("");

  return { context: { st, setSt } };
}

function MyHelper(prop) {
  const ActualComponent = prop.capture;

  return <ActualComponent />;
}

function MyComponent() {
  const { context } = StateHelper();

  const capturedComponent = () => (
    <input
      value = {context.st}
      onChange = {(e) => {
        context.setSt(e.target.value);
      }}
    />
  );

  return <MyHelper capture = {capturedComponent} />;
}

Runnable Fiddle Например, 2

Кажется, я запутался в одной из основ.

Например, 1, когда я печатаю, я не теряю фокус на компоненте ввода.
Например, 2, на каждой набранной букве я теряю фокус.

В обоих этих примерах Math.random() изменяется, поэтому они оба перерисовываются.

Я не знаю, в чем разница и почему я продолжаю терять внимание, например. 2 ?

Я пытаюсь следовать, например. 2, так как это помогает мне лучше управлять своим кодом, но я не могу его понять. Что я не понимаю в повторном рендеринге компонентов реагирования и как это исправить?

Ваши примеры ни в коей мере не верны для React. Пожалуйста, переформатируйте это, чтобы они были последовательно, а не рядом.

AKX 04.07.2024 14:21

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

Konrad 04.07.2024 14:22

Пожалуйста, также покажите, как вы используете эти компоненты – поскольку они называются myComponent вместо MyComponent, для начала вам придется пройти дополнительные этапы (вы не можете сделать <myComponent />, поскольку JSX интерпретирует myComponent как имя внутренний элемент).

AKX 04.07.2024 14:24

принял к сведению, я обновляю код как можно скорее

BumbleBee 04.07.2024 14:25

Я пытаюсь добавить скрипку, чтобы воспроизвести проблему.

BumbleBee 04.07.2024 14:32

@AKX, я обновил код, добавив работоспособную скрипту, кажется, например. 2 вводил в заблуждение

BumbleBee 04.07.2024 15:15

@Конрад, кажется, мой например. 2 ввел в заблуждение, я добавил работоспособную скрипку

BumbleBee 04.07.2024 15:15

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

BumbleBee 04.07.2024 15:16

Та же проблема stackoverflow.com/questions/59715158/…

Konrad 04.07.2024 15:59
Поведение ключевого слова "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) для оценки ваших знаний,...
0
9
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Ваша const capturedComponent = () => ( — это внутренняя функция, идентичность которой меняется при каждом вызове объявляющего ее компонента.

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

Более подробную информацию см. в документации по правилу React ESlint для этой проблемы.

а что в примере 1? Почему мы не теряем фокус, даже если весь компонент перерисовывается?

BumbleBee 04.07.2024 15:41

Повторный рендеринг @BumbleBee не является проблемой. Перемонтирование есть. Компонент во втором примере уничтожается и создается заново каждый раз, когда вы нажимаете клавишу.

Konrad 04.07.2024 15:58

кажется, полезно почитать: ferreira.io/posts/re-mounting-vs-re-rendering

BumbleBee 04.07.2024 16:31

@AKX, в предоставленной вами ссылке упоминается решение не использовать запомненную функцию для захвата значения переменной, тогда я не понимаю, как зафиксировать значение переменной, когда вам нужно сказать, сохраняйте состояние на уровне страницы? Выше я не могу переместить StateHelper() за пределы <MyComponent/>, потому что хочу, чтобы состояние сохранялось в <MyComponent>. Есть ли у вас какие-либо предложения?

BumbleBee 04.07.2024 17:21

Вы переместите capturedComponent наружу MyComponent и передадите ему st и setSt в качестве реквизита (или используете API контекста React в более сложных случаях).

AKX 04.07.2024 17:40

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

BumbleBee 04.07.2024 17:49

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