Подавить onChange и использовать onBlur только для компонента ввода React

У меня есть компонент с именем Test, который получает 2 реквизита: CurrentPage и OnPageRequest: (currentPage: number) => void

Когда родительский компонент использует Test, он устанавливает номер текущей страницы в своем состоянии. Когда вы обновляете поле ввода ниже, это значение передается обратно родительскому компоненту через OnPageRequest как:

OnPageRequest(e.target.value);

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

Тестовый компонент:

const handlePageNumberBlur = (e) => {
    OnPageRequest(e.target.value);
}

render() {
    return (
        <input
            title = "Current Page"
            onBlur = {handlePageNumberBlur}
            aria-label = "Current Page"
            min = "1"
            max = {TotalPages}
            placeholder = "1"
            type = "number"
            value = {this.props.CurrentPage} />
    )
}

Я пытаюсь написать Test таким образом, чтобы он возвращал только что введенное значение только тогда, когда запускается событие onBlur. Но я узнал, что с приведенным выше кодом он никогда не обновляет value. Это происходит только в том случае, если у меня есть событие onChange, где я делаю: OnPageRequest(e.target.value);

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

ПРИМЕР: https://codesandbox.io/s/kumuc

Не уверен, что это связано, но я думаю, что эта проблема может помочь вам решить вашу проблему: stackoverflow.com/questions/41832389/…

Thomas Lombart 27.05.2019 09:02

как будет обновляться входное значение, если у вас нет onChange, поскольку ваш ввод контролируется? и если входное значение не обновляется, ваша функция handlePageNumberBlur будет каждый раз получать одно и то же значение.

Sameer Reza Khan 27.05.2019 09:04

Можно ли поделиться своим кодом в песочнице кода?

A.K.47 27.05.2019 11:51

@ AK47 Я обновил начальный пост образцом

blankface 27.05.2019 13:11
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
4
1 108
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Попробуйте использовать defaultValue вместо value. Свойство defaultValue устанавливает значение только для ввода при начальном рендеринге, и вам не нужно будет обновлять его, если значение свойства изменится.

<input
    { ... }
    defaultValue = {this.prop.CurrentPage}
/>

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

Если вам нужно обновлять ввод после первого рендеринга, вы можете обновить его значение, используя ссылки и метод жизненного цикла componentDidUpdate.

class TestComponent extends React.Component {
    constructor(props) {
        super(props);
        this.inputRef = React.createRef();
    }

    componentDidUpdate(prevProps) {
        if (this.inputRef.current.value != this.props.CurrentPage) {
            this.inputRef.current.value = this.props.CurrentPage;
        }
    }

    /* ... */

    render() {
        return <input 
            { ... }
            defaultValue = {this.props.CurrentPage}
            ref = {this.inputRef}
        />
    }
}

Это по-прежнему не обновляет значение, если я не устанавливаю onChange

blankface 27.05.2019 13:22

@ZeroDarkThirty Вы не можете установить value и defaultValue одновременно. Попробуйте удалить опору value.

Rallen 27.05.2019 13:24

Хорошо, я реализовал решение. Буду признателен, если вы посмотрите codeandbox.io/s/kumuc

blankface 27.05.2019 13:35

Работает по назначению. Ввод можно редактировать и только при размытии появляется консольное сообщение.

Rallen 27.05.2019 13:37

Похоже, даже если я уберу useEffect, он все равно будет работать, как задумано. Почему это?

blankface 27.05.2019 13:40

Это благодаря реквизиту defaultValue. Опция value всегда перезаписывает значение input, которое также включает изменения, внесенные пользователем. Вот почему должен быть обработчик onChange. Но с defaultValueinput управляет самим значением, потому что React переопределяет значение ввода только при первом рендеринге.

Rallen 27.05.2019 13:48

Ах хорошо. Поэтому, когда я проверяю элемент, value перезаписывается каждый раз, когда срабатывает onBlur? По сути, это передача значения родительскому компоненту, который снова устанавливает defaultValue?

blankface 27.05.2019 14:06

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

Rallen 27.05.2019 14:09

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