У меня есть компонент с именем 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
как будет обновляться входное значение, если у вас нет onChange
, поскольку ваш ввод контролируется? и если входное значение не обновляется, ваша функция handlePageNumberBlur
будет каждый раз получать одно и то же значение.
Можно ли поделиться своим кодом в песочнице кода?
@ AK47 Я обновил начальный пост образцом
Попробуйте использовать 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
@ZeroDarkThirty Вы не можете установить value
и defaultValue
одновременно. Попробуйте удалить опору value
.
Хорошо, я реализовал решение. Буду признателен, если вы посмотрите codeandbox.io/s/kumuc
Работает по назначению. Ввод можно редактировать и только при размытии появляется консольное сообщение.
Похоже, даже если я уберу useEffect
, он все равно будет работать, как задумано. Почему это?
Это благодаря реквизиту defaultValue
. Опция value
всегда перезаписывает значение input
, которое также включает изменения, внесенные пользователем. Вот почему должен быть обработчик onChange
. Но с defaultValue
input
управляет самим значением, потому что React переопределяет значение ввода только при первом рендеринге.
Ах хорошо. Поэтому, когда я проверяю элемент, value
перезаписывается каждый раз, когда срабатывает onBlur? По сути, это передача значения родительскому компоненту, который снова устанавливает defaultValue?
Нет. defaultValue
устанавливается только один раз, даже если он обновляется. Элемент просто сохраняет свое значение, потому что React не перезаписывает его, поскольку это поведение по умолчанию при использовании реквизита value
. Я рекомендую вам ознакомиться с темой Управляемые компоненты и Неконтролируемые компоненты.
Не уверен, что это связано, но я думаю, что эта проблема может помочь вам решить вашу проблему: stackoverflow.com/questions/41832389/…