如何在React.js中使用useState创建对象?将tags从数组改对象可行吗?
完全可行,这里给你两种实现方案
你想要把tags改成[{key1: "用户输入标签", key2: "用户输入标签2"...}]这种对象嵌套数组的结构完全没问题,下面是具体实现:
方案1:单对象存所有标签(匹配你给出的示例结构)
这种方案是数组里只存一个对象,所有标签都以键值对的形式放在这个对象里:
import React from "react"; const TagsInput = (props) => { // 初始状态为包含空对象的数组 const [tags, setTags] = React.useState([{}]); const addTags = event => { // 仅在按下回车键时添加标签 if (event.key !== 'Enter') return; const inputValue = event.target.value.trim(); // 空输入不处理 if (!inputValue) return; // 生成唯一键名,用已有标签的数量+1命名 const tagCount = tags.flatMap(obj => Object.keys(obj)).length; const newKey = `key${tagCount + 1}`; // 用函数式更新避免闭包问题 setTags(prevTags => { const updatedObj = {...prevTags[0]}; updatedObj[newKey] = inputValue; return [updatedObj]; }); // 清空输入框 event.target.value = ""; }; // 渲染已添加的标签 const renderTags = () => { const tagObj = tags[0]; if (!Object.keys(tagObj).length) return null; return Object.entries(tagObj).map(([key, text]) => ( <span key={key} className="tag-item"> {text} </span> )); }; return ( <div className="tags-input"> {/* 渲染已添加的标签 */} {renderTags()} <input type="text" onKeyUp={addTags} placeholder="按回车添加标签" /> </div> ); }; export default TagsInput;
方案2:数组存多个标签对象(更灵活的结构)
如果业务上需要每个标签是独立的对象,比如[{key1: "标签1"}, {key2: "标签2"}],这种结构操作起来更灵活,实现如下:
import React from "react"; const TagsInput = (props) => { // 初始状态为空数组 const [tags, setTags] = React.useState([]); const addTags = event => { if (event.key !== 'Enter') return; const inputValue = event.target.value.trim(); if (!inputValue) return; const newKey = `key${tags.length + 1}`; // 往数组里新增标签对象 setTags(prevTags => [...prevTags, {[newKey]: inputValue}]); event.target.value = ""; }; const renderTags = () => { if (!tags.length) return null; return tags.map((tagObj) => { const [key, text] = Object.entries(tagObj)[0]; return ( <span key={key} className="tag-item"> {text} </span> ); }); }; return ( <div className="tags-input"> {renderTags()} <input type="text" onKeyUp={addTags} placeholder="按回车添加标签" /> </div> ); }; export default TagsInput;
注意点
- 两种方案都加了回车键判断,解决原代码中任意按键都添加标签的问题
- 键名用
keyX的形式保证唯一性,你也可以换成时间戳、UUID等更稳妥的唯一标识 - 用函数式更新
setTags(prev => ...)避免因闭包导致的状态更新错误
内容的提问来源于stack exchange,提问作者user20271619
相关产品推荐
相关产品推荐

