Мне кажется, что я не могу решить бесконечную проблему l oop в моем проекте реагирования.
Я работаю над приложением реакции ежедневного журнала. Позвольте мне кратко объяснить проект. Вот изображение кода для быстрого просмотра:
Тот же код доступен внизу.
Структура ( сверху вниз)
- Компонент
DailyLog
имеет форму, в которой используются Question
компоненты, в которые передаются реквизиты. - Компонент
Question
использует реквизиты для отображения вопрос и описание. Он также содержит компонент Input
, в который далее передаются реквизиты. - Компонент
Input
берет реквизиты и отображает соответствующее поле ввода формы.
Лог c (снизу вверх)
- Компонент
Input
обрабатывает свой собственный inputState
. Состояние изменяется, когда пользователь что-то вводит, и срабатывает onChangeHandler
. - Компонент
Input
также имеет хук useEffect()
, который вызывает функцию onInput()
, которая была передана в качестве подпорки из DailyLog
. onInputHandler()
в компоненте DailyLog
обновляет formState
, то есть состояние всей формы, содержащее все значения поля ввода. formState
изменяется в зависимости от того, какое поле ввода заполнено в данный момент. onInputHandler()
использует хук useCallback()
, который должен остановить бесконечное l oop, вызванное любым родителем / дочерним элементом повторно делает. Но это не работает: frowning:
Что не так в коде? Что мне здесь не хватает? Код представлен ниже:
//DailyLog.js
import React, { useState, useCallback } from 'react';
import Question from '../components/FormElements/Question';
import questionData from '../components/DailyLog/questionData';
import './DailyLog.css';
const DailyLog = () => {
const [formState, setFormState] = useState();
const onInputHandler = useCallback(
(inputId, inputValue) => {
setFormState({
...formState,
[inputId]: inputValue,
});
},
[formState]
);
return (
<main className="container">
<form action="" className="form">
<Question
id="title"
element="input"
type="text"
placeholder="Day, date, calendar scheme"
onInput={onInputHandler}
/>
<Question
id="focus"
question={questionData.focusQuestion}
description={questionData.focusDescription}
element="textarea"
placeholder="This month's focus is... This week's focus is..."
onInput={onInputHandler}
/>
</form>
</main>
);
};
export default DailyLog;
//Question.js
import React from 'react';
import Input from './Input';
import './Question.css';
const Question = props => {
return (
<div className="form__group">
{props.question && (
<label className="form__label">
<h2>{props.question}</h2>
</label>
)}
<small className="form__description">{props.description}</small>
<Input
id={props.id}
element={props.element}
type={props.type}
placeholder={props.placeholder}
onInput={props.onInput}
/>
</div>
);
};
export default Question;
//Input.js
import React, { useState, useEffect } from 'react';
import './Input.css';
const Input = props => {
const [inputState, setInputState] = useState();
const { id, onInput } = props;
useEffect(() => {
onInput(id, inputState);
}, [id, onInput, inputState]);
const onChangeHandler = event => {
setInputState(event.target.value);
};
// check if question element type is for input or textarea
const element =
props.element === 'input' ? (
<input
id={props.id}
className="form__field"
type={props.type}
value={inputState}
placeholder={props.placeholder}
onChange={onChangeHandler}
/>
) : (
<textarea
id={props.id}
className="form__field"
rows="1"
value={inputState}
placeholder={props.placeholder}
onChange={onChangeHandler}
/>
);
return <>{element}</>;
};
export default Input;