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

React中如何从用户输入生成嵌套列表并绑定对应键值

问题解决:React中实现嵌套列表的用户输入与渲染

核心问题修复思路

  1. 传递当前文件夹键值到提交函数:遍历文件夹时,将当前键值作为参数关联到提交逻辑,明确要往哪个文件夹下添加项。
  2. 正确更新React状态:不能直接修改原state对象,必须创建新的对象副本进行更新,确保React能检测到变化并触发重渲染。
  3. 渲染嵌套子项:在每个文件夹的DOM结构中,遍历对应数组,渲染嵌套的列表项。

修改后的完整代码

import { useState } from 'react';
import { FaFolder } from 'react-icons/fa';
// 假设touchable和Popup是已导入的组件

const Input = () => {
    // 初始化嵌套列表状态,示例结构
    const [folder, setFolder] = useState({
        user1: [],
        user2: []
    });
    const [item, setItem] = useState('');
    // 保存当前操作的文件夹名称
    const [currentFolder, setCurrentFolder] = useState('');

    const addPackage = (e) => {
        setItem(e.target.value);
    };

    const submitPackage = () => {
        if (!currentFolder || !item.trim()) return;
        // 创建新的状态副本,避免直接修改原state
        const updatedFolder = {
            ...folder,
            [currentFolder]: [...folder[currentFolder], item.trim()]
        };
        setFolder(updatedFolder);
        setItem(''); // 清空输入框
    };

    // 补全创建文件夹的逻辑
    const [newFolderName, setNewFolderName] = useState('');
    const addItem = (e) => {
        setNewFolderName(e.target.value);
    };
    const submitValue = () => {
        if (!newFolderName.trim()) return;
        const folderName = newFolderName.trim();
        if (!folder[folderName]) {
            setFolder({
                ...folder,
                [folderName]: []
            });
        }
        setNewFolderName('');
    };

    return (
        <div>
            <h2 className='header'>drag and drop list</h2>
            <div className="compA">
                <strong>compA</strong><br/>
                <Popup trigger={<touchable>file</touchable>} position="right top">
                    <>
                        <table bgcolor='white'>
                            <tbody>
                                <tr><td><strong>create package:</strong></td></tr>
                                <tr><td><input type='text' value={newFolderName} onChange={addItem}/></td></tr>
                                <tr><td><button onClick={submitValue}>create</button></td></tr>
                            </tbody>
                        </table>
                    </>
                </Popup>
                <hr/>
                {Object.entries(folder).map(([folderKey, folderItems]) => (
                    <div align='left' key={folderKey}>
                        {/* 打开弹窗时记录当前操作的文件夹 */}
                        <Popup 
                            trigger={<touchable><FaFolder/>{folderKey}</touchable>} 
                            position="right top"
                            onOpen={() => setCurrentFolder(folderKey)}
                        >
                            <>
                                <table bgcolor='white'>
                                    <tbody>
                                        <tr>
                                            <td><strong>package:</strong></td>
                                            <td><input type='text' defaultValue={folderKey} disabled/></td>
                                        </tr>
                                        <tr>
                                            <td><strong>create class:</strong></td>
                                            <td><input type='text' value={item} onChange={addPackage}/></td>
                                        </tr>
                                        <tr><td><button onClick={submitPackage}>create</button></td></tr>
                                    </tbody>
                                </table>
                            </>
                        </Popup>
                        <br/>
                        {/* 渲染当前文件夹下的嵌套子项 */}
                        <ul style={{ marginLeft: '20px' }}>
                            {folderItems.map((itemName, index) => (
                                <li key={index}>{itemName}</li>
                            ))}
                        </ul>
                    </div>
                ))}
            </div>
            <div className="compB"></div>
        </div>
    );
};

export default Input;

关键改动说明

  • 关联当前操作文件夹:通过Popup的onOpen事件,打开弹窗时自动记录当前文件夹的键值,提交时直接使用该值定位目标数组。
  • Immutable状态更新:使用扩展运算符创建新的对象和数组副本,保证状态更新符合React的不可变原则,触发组件重渲染。
  • 渲染嵌套内容:在每个文件夹的DOM节点下,添加列表遍历对应数组,实时展示用户添加的嵌套项。
  • 补全文件夹创建逻辑:完善原代码中缺失的新建文件夹功能,确保能生成空的嵌套容器。

内容的提问来源于stack exchange,提问作者Rajesh Yadav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 17:05:24