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.
Когда это он стаёт неконтроллируемым?
  • Вопрос задан
  • 447 просмотров
Решения вопроса 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 при изменении значения инпута.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы
27 нояб. 2024, в 13:07
10000 руб./за проект
27 нояб. 2024, в 12:53
70000 руб./за проект
27 нояб. 2024, в 12:50
25000 руб./за проект