You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React父子组件中textarea添加onChange后默认值消失问题

问题解决:Textarea 初始值保留+实时更新内容

你的核心问题是混用非受控组件(defaultValue)和受控组件逻辑,加上子组件props处理错误、冗余属性导致初始值丢失/重置。以下是具体修复方案和代码:

问题根源

  1. 子组件props解构错误,无法正确获取父组件传递的参数
  2. Textarea 同时设置 defaultValue 和自定义状态,加上多余的 contentEditable 属性,引发渲染冲突
  3. 状态更新时传递旧值,父组件无法获取最新输入内容

修复方案

1. 子组件改造(受控组件模式)

  • 正确解构props,移除冗余的contentEditable属性
  • 使用受控组件:用value绑定状态,替代defaultValue
  • 实时传递最新输入值给父组件

2. 父组件保持状态同步

  • 采用函数式更新方式,避免闭包导致的旧状态问题,确保列表项正确更新

修复后的代码

父组件

const Main = () => {
    const notes = [
        {
            id: 1,
            title: "What is React? ",
            content: "React is a JavaScript library that aims to simplify development of visual interfaces."
        },
        {
            id: 2,
            title: "What is Java?",
            content: "Java is a most popular, object-oriented, widely used programming language and platform that is utilized for Android development, web development, artificial intelligence, cloud applications, and much more."
        }
    ];
    const [mynote, setNote] = useState(notes);
    const [isActive, setisActive] = useState([]);
  
    const handleClick = (id) => {
       setisActive(id);
    };

    const pullcontent = (id, plnote) => {
        setNote(prevNotes => prevNotes.map(obj => {
            if (obj.id === parseInt(id)) {
                return {...obj, content: plnote};
            } else {
                return obj;
            }
        }));
    };

    return (
        <div className='main'>
            <div className="rightnote note-cont">
                <div className="contents">
                    {
                        mynote.map((obj) => (
                            <div className={`conts ${isActive === obj.id ? 'cont-active':'cont-inactive'}`} key={obj.id}>
                                <div className="con">
                                    <Content 
                                        notecontent={obj.content} 
                                        noteid={obj.id} 
                                        onCh={(pullednote) => pullcontent(obj.id, pullednote)}
                                    />
                                </div>
                            </div>
                        ))
                    }
                </div> 
            </div>
        </div>
    );
};

export default Main;

子组件

import React, { useState, useEffect } from 'react';
import './Content.css';

const Content = ({ notecontent, noteid, onCh }) => {
    const [note, setnote] = useState(notecontent);

    // 监听父组件传递的内容变化,同步子组件状态
    useEffect(() => {
        setnote(notecontent);
    }, [notecontent]);

    const changeHandler = (e) => {
        const newValue = e.target.value;
        setnote(newValue);
        onCh(newValue);
    };

    return (
        <div className="content">
            <textarea 
                name="" 
                id={noteid} 
                value={note} 
                cols="164" 
                rows="48" 
                onChange={changeHandler} 
            />
        </div>
    );
};

export default Content;

关键说明

  • 改用受控组件后,textarea的值完全由note状态控制,初始值从父组件notecontent获取,确保初始内容正常显示
  • 添加useEffect监听父组件内容变化,保证父子组件状态同步
  • 移除contentEditable和suppressContentEditableWarning,此类属性不适用于textarea组件
  • 父组件使用prevNotes函数式更新,避免闭包导致的状态更新异常

内容的提问来源于stack exchange,提问作者Akash Kr. Das

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 09:58:09