Задать вопрос
TheSnegok
@TheSnegok

Как вызывать useState в дочерней компоненте и менять state сверху?

Мне нужно чтобы при нажатии на букву она добавлялась в value в инпут в компоненту выше:
основа:
function App() {
	const [value, setValue] = useState('');
	return (
		<div className="App">
			<main>
				<div className="gliph">
					<div className="gliphArea">
						<h1>Gliphs</h1>
						<input className="inputLine" value={value} readOnly />
						<div className="gliphAlphabet">
							<Gliph value={value} set={() => setValue()} />
						</div>
					</div>
				</div>
			</main>
			<div className="history">
				<input type="text" className="inputLine" readOnly />
			</div>
		</div>
	);
}

Дочерний компонент:
const alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];

const Gliph = ({ value, set }) => {
    const handleClick = (letter) => {
        set(value + letter);
    }
    return (
        <>
            {alphabet.map(l => <div key={l} className="gliphMine" onClick={() => handleClick(l)}>{l}</div>)}
        </>
    )
}

Код ошибки:
A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.
Когда это он стаёт неконтроллируемым?
  • Вопрос задан
  • 530 просмотров
Подписаться 1 Средний 4 комментария
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Мидл фронтенд-разработчик
    5 месяцев
    Далее
  • Javascript.ru
    Курс по React
    5 недель
    Далее
  • Нетология
    Fullstack-разработчик на Python + нейросети
    20 месяцев
    Далее
Решения вопроса 2
Krasnodar_etc
@Krasnodar_etc
fundraiseup
Замените
set={() => setValue()}

На
set={setValue}

Иначе вы всегда функцию setValue без аргументов вызываете
И вообще старайтесь не делать анонимные функции при передаче пропсов, это удар по оптимизации
Ответ написан
Alexandroppolus
@Alexandroppolus
кодир
Не поленился скопипастить и проверить. Ошибка не выскочила.
Зато слегонаца пооптимизировал (написано на TS, у меня подопытная заготовка на нем):
type Pr = {
  set: React.Dispatch<React.SetStateAction<string>>
}

const Gliph: React.FC<Pr> = React.memo(({ set }) => {
  console.log('render Gliph')
  const handleClick = (letter: string) => {
    set((value) => value + letter)
  }
  return (
    <>
      {alphabet.map((l) => (
        <button type="button" key={l} className="gliphMine" onClick={() => handleClick(l)}>
          {l}
        </button>
      ))}
    </>
  )
})

export const App: React.FC = () => {
  const [value, setValue] = useState('')
  console.log('render App')

  return (
    <div>
      <input className="inputLine" value={value} readOnly />
      <Gliph set={setValue} />
    </div>
  )
}


при таком раскладе не случается перерендер Gliph при изменении значения инпута.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
ITK academy Нижний Новгород
от 50 000 до 90 000 ₽
IT ATLAS Москва
от 200 000 до 250 000 ₽
ITK academy Казань
от 50 000 до 90 000 ₽