2

我似乎无法解决我的反应项目中的无限循环问题。

我正在开发一个每日日志反应应用程序。让我简要解释一下这个项目。这是快速查看的代码图片:

这是用于快速查看的代码图片

底部提供了相同的代码。

结构(从上到下)

  1. DailyLog组件有一个表单,该表单使用Question传递道具的组件。
  2. Question组件使用道具来显示问题和描述。它还包含一个Input组件,props 被进一步传递到该组件中。
  3. Input组件获取道具并呈现适当的表单输入字段。

逻辑(从下到上)

  1. Input组件处理它自己的inputState. 当用户输入某些内容并onChangeHandler触发时,状态会发生变化。
  2. Input组件还有一个useEffect()钩子,该钩子调用onInput()作为道具从DailyLog.
  3. onInputHandler()组件中的更新DailyLog包含formState所有输入字段值的表单范围状态。根据formState当时填写的输入字段进行修改。
  4. 使用应该停止由任何父/子重新渲染引起的无限循环onInputHandler()的钩子。useCallback()但它不起作用:皱眉:

代码有什么问题?我在这里想念什么?下面提供的代码:

//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;

4

1 回答 1

0

从 useEffect 敏感列表中删除 id 和 onInput

useEffect(() => {
        onInput(id, inputState);
}, [inputState]);

并将 inputState 的默认值设置为 '' 如下:

const [inputState, setInputState] = useState('');

为了防止“一个组件正在将一个不受控制的文本类型的输入更改为 ReactJS 中的受控错误”。你也可以初始化formState:

const [formState, setFormState] = useState({title:'', focus:''});
于 2020-04-06T13:26:01.527 回答