资讯动态

30-seconds-of-react 片段解析:非受控 textarea 组件(TextArea)的实现与父子通信

发布时间:2026/10/13 2:08:33 来源:尧图企业网站定制
前端教程【免费下载链接】30-seconds-of-reactShort React code snippets for all your development needs项目地址https://gitcode.com/gh_mirrors/30/30-seconds-of-react点击查看免费下载TextArea是 30-seconds-of-react 仓库中一个短小精悍的非受控文本域组件片段源文件位于 snippets/text-area.md。它用不到 20 行代码演示了 React 非受控表单元素的核心范式用defaultValue指定初始值、用onChange事件把最新值通过回调函数上报给父组件。读完本文你将掌握非受控组件的实现原理、它与受控组件的取舍方法以及如何基于该片段扩展出带字数限制、接入表单状态管理的实战版本。片段概览它解决什么问题在 React 中受控与非受控是表单元素input、textarea、select的两种状态管理模式。本片段针对textarea实现的是非受控方案文本域的当前值由 DOM 自己维护组件内部不持有状态只负责两件事用父组件传下来的defaultValue作为初始值在用户输入时通过onChange事件触发onValueChange回调把新值上报给父组件。从片段文件的 front mattersnippets/text-area.md可以看到它被标记为type: snippet、tags: [components, input]dateModified为 2020-11-25属于仓库中组件 输入分类的经典片段。它和仓库内的 uncontrolled-input.md非受控 input、controlled-input.md受控 input构成一组互相印证的姊妹片段。核心机制非受控组件与 defaultValue组件核心实现如下snippets/text-area.mdconst TextArea ({ cols 20, rows 2, defaultValue, onValueChange, ...rest }) { return ( textarea cols{cols} rows{rows} defaultValue{defaultValue} onChange{({ target: { value } }) onValueChange(value)} {...rest} / ); };拆解这段代码可以提炼出三个关键设计1.defaultValue只负责初始值不负责持续控制非受控元素的标志性 prop 就是defaultValue。React 只在元素首次挂载时读取它一次将其写入 DOM此后即便父组件再次传入不同的defaultValue已经显示在页面上的文本也不会随之变化——因为值的所有权在 DOM 手里React 不再插手。这与受控元素中valueprop 的双向同步语义有本质区别。2.onChange是值上报的唯一通道onChange{({ target: { value } }) onValueChange(value)}这里对事件对象做了解构({ target: { value } })等价于取出事件对象上的target.value再直接作为参数调用onValueChange。也就是说用户每敲一个字符父组件都会收到一个最新的字符串值。父组件拿到值后如何存储useState、useForm或直接打印完全由父组件自己决定。3.{...rest}透传让组件保持可复用解构掉cols、rows、defaultValue、onValueChange之后剩余的所有 props如placeholder、name、id、disabled等都会通过{...rest}原样透传给底层的textarea。这正是包装原生元素时最常用的可复用性技巧调用方可以按需附加任意原生属性无需在组件里逐一声明。此外cols 20、rows 2为这两个布局属性提供了默认值未显式传入时文本域按 20 列 2 行渲染。使用示例父组件如何接收值仓库给出的渲染示例[snippets/text-area.md](https://link.gitcode.com/i/63699bcc18bbc70056810d0535c88da5#L34-L40如下ReactDOM.createRoot(document.getElementById(root)).render( TextArea placeholderInsert some text here... onValueChange{val console.log(val)} / );这个示例传递了两个信息placeholder未在组件 props 中声明它正是通过{...rest}透传到达textarea的验证了透传机制的实际效果onValueChange在这里直接接到了console.log每次输入都会在控制台打印当前值。在实际项目中你通常会把它接到setState或表单状态管理函数上。示例使用ReactDOM.createRoot(...).render(...)渲染这与仓库统一采用的片段模板snippet-template.md保持一致也说明该片段面向 React 18 及以上版本的挂载方式。受控 vs 非受控仓库内对照实现要真正理解TextArea的价值最好把它和仓库中的受控版本对照来看。受控 inputcontrolled-input.mdconst ControlledInput ({ value, onValueChange, ...rest }) { return ( input value{value} onChange{({ target: { value } }) onValueChange(value)} {...rest} / ); };非受控 inputuncontrolled-input.mdconst UncontrolledInput ({ defaultValue, onValueChange, ...rest }) { return ( input defaultValue{defaultValue} onChange{({ target: { value } }) onValueChange(value)} {...rest} / ); };对照后差异一目了然维度受控组件value非受控组件defaultValue值的所有权父组件React stateDOM 自身当前值的来源父组件每次渲染传入的valuepropDOM 内部状态仅首次挂载读defaultValue父组件能否事后强制改值能更新valueprop 即可不能defaultValue更新不会反映到已渲染的 DOM状态管理成本父组件必须维护并回传 state父组件无需持有值只负责接收回调适用场景需要校验、联动、重置、格式化等强控制场景初始值固定、无需程序化干预的简单表单本片段的TextArea与 uncontrolled-input.md 的实现思路完全一致只是把原生元素换成了textarea并额外提供了cols/rows的默认值。如果你需要父组件能在任意时刻重置/覆盖文本域内容的能力则应改用valueonChange的受控写法。实战进阶带限制的 textarea 变体基础版TextArea只解决值上报不限制内容。仓库另外提供了两个基于状态管理Hooks的限制版本可作为该片段的直接延伸。字符限制版limited-textarea.mdconst LimitedTextarea ({ rows, cols, value, limit }) { const [content, setContent] React.useState(value.slice(0, limit)); const setFormattedContent React.useCallback( text { setContent(text.slice(0, limit)); }, [limit, setContent] ); return ( textarea rows{rows} cols{cols} onChange{event setFormattedContent(event.target.value)} value{content} / p {content.length}/{limit} /p / ); };它用useState持有content用useCallback把截断到limit字符的逻辑记忆化并渲染内容长度/限制值的计数器。注意它与基础版的本质区别这里改用了valueonChange的受控模式——因为必须由 React 状态在每次输入后执行slice(0, limit)截断并回写显示值非受控模式无法做到这一点。**单词限制版limited-word-textarea.md**思路相同、算法不同用String.prototype.split( )把输入拆成单词数组配合Array.prototype.filter(Boolean)过滤空串当单词数超过limit时用words.slice(0, limit).join( )截断同时用useEffect在首次渲染时格式化初始value并在下方显示wordCount/limit计数。这两个变体与TextArea共同覆盖了文本域的常见需求纯上报非受控、受控截断字符/单词限制可以根据是否需要程序化干预内容来选择对应模式。组合应用接入表单状态管理onValueChange回调的设计让TextArea可以无缝接入仓库中的表单 Hook——use-form.mdconst useForm initialValues { const [values, setValues] React.useState(initialValues); return [ values, e { setValues({ ...values, [e.target.name]: e.target.value }); } ]; };useForm返回[values, setValues]其更新函数依赖事件对象上的e.target.name与e.target.value。把TextArea的onValueChange接上setValues再把name通过{...rest}透传下去即可让文本域与表单状态联动const Form () { const [values, setValues] useForm({ bio: }); return ( form onSubmit{e { e.preventDefault(); console.log(values); }} TextArea namebio rows{4} cols{40} defaultValue onValueChange{e setValues({ target: { name: bio, value: e } })} / button typesubmitSubmit/button /form ); };需要说明的是基础版TextArea的回调直接传字符串onValueChange(value)而useForm的更新函数期望事件对象形状因此接入时需要在父组件做一次薄薄的适配封装如果你偏好完全对齐事件对象也可以参考useForm的写法自行调整回调签名。常见误区与注意事项结合源码与 React 的受控/非受控语义使用本片段时有几点值得留意defaultValue更新无效是预期行为不是 bug。非受控元素的值由 DOM 持有父组件传入新的defaultValue不会覆盖屏幕上已显示的内容。若需要程序化重置/覆写请切换到受控模式参考 limited-textarea.md 的value用法。onChange与受控的value不能混用。在一个元素上同时使用value和defaultValue会导致 React 告警且行为不可预测本片段只使用defaultValue语义自洽。回调是通知而非同步。onValueChange只是把值告诉父组件父组件是否保存、保存到哪里state、ref、外部 store都不影响 DOM 中已显示的文本——这正是非受控模式父组件零状态维护特性的来源。事件解构假设target存在。React 的onChange事件是SyntheticEvent其target必然指向触发的 DOM 元素因此({ target: { value } })在原生textarea上是安全的但如果把它泛化到自定义组件上需要自行保证事件形状一致。限制版本是受控的。字符/单词限制必须依赖 React 状态回写截断后的内容因此 limited-textarea.md 与 limited-word-textarea.md 走的是value路线与本文的defaultValue路线恰好互补二者并非同一模式的重复。小结TextAreasnippets/text-area.md是 30-seconds-of-react 中非受控输入元素家族的一员它用defaultValue定义初始值用onChangeonValueChange回调把最新值上报给父组件配合{...rest}透传保持极高的可复用性。与仓库内 uncontrolled-input.md、controlled-input.md、limited-textarea.md、limited-word-textarea.md、use-form.md 等片段对照阅读可以完整掌握 React 表单元素从非受控上报到受控截断再到表单状态集成的完整技术谱系。该片段及其姊妹片段均遵循仓库 README.md 中声明的 CC-BY-4.0 许可可自由参考与再实现。赞分享前端教程【免费下载链接】30-seconds-of-reactShort React code snippets for all your development needs项目地址https://gitcode.com/gh_mirrors/30/30-seconds-of-react点击查看免费下载相关推荐30-seconds-of-react用 React Hooks 实现带词数限制的 textarea 组件LimitedWordTextarea30 seconds of react用 React Hooks 实现带词数限制的 textarea 组件LimitedWordTextarea 本文以前端教程30-seconds-of-react用 ControlledInput 代码片段彻底掌握 React 受控输入组件30 seconds of react用 ControlledInput 代码片段彻底掌握 React 受控输入组件 导读 本文以 30 seconds o前端教程30 seconds of React用非受控 Select 组件实现回调式下拉选择30 seconds of React用非受控 Select 组件实现回调式下拉选择 本指南围绕 30 seconds of react 仓库中的 Selec前端教程上一篇Tsuru平台即服务评估企业采用决策指南下一篇如何快速上手Webcrumbs零代码React网站开发的终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑