javascript - 如何优化 React 模式以允许用户将新数据输入到状态中

标签 javascript reactjs user-interface frontend

如何从页面获取用户数据并使用它在react.js 程序中创建元素?

我有一个文件,app.js。文件中声明的第一件事是几个常量,用于玩具数据:

const book1 = [
    {id: uuid(), content: 'reflections'}
];
const book2 = [
    {id: uuid(), content: 'arising'},
]

和一个常量将它们拉入列


const clusterColumns =
    {
        [uuid()]: {
            name: 'Book 1',
            items: book1
        },
        [uuid()]: {
            name: 'Book 2',
            items: book2
        },
    };

还有第三个常量,当我在页面上移动数据时清理数据


const onDragEnd = (result, columns, setColumns ) => {
    if(!result.destination ) return;
    const {source, destination} = result;
    if (source.droppableId!==destination.droppableId) {
        const sourceColumn = columns[source.droppableId];
        const destColumn = columns[destination.droppableId];
        const sourceItems = [...sourceColumn.items];
        const destItems = [...destColumn.items];
        const [removed] = sourceItems.splice(source.index, 1);
        destItems.splice(destination.index, 0, removed);
        setColumns({
            ...columns,
            [source.droppableId]:{
                ...sourceColumn,
                items: sourceItems,
            },
            [destination.droppableId]:{
                ...destColumn,
                items: destItems
            }
        })
    }
    else {
        const column = columns[source.droppableId];
        const copiedItems = [...column.items];
        const [removed] = copiedItems.splice(source.index, 1);
        copiedItems.splice(destination.index, 0, removed)
        setColumns({
            ...columns,
            [source.droppableId]: {
                ...column,
                items: copiedItems
            }
        })
    }
};

app.js 文件的主要部分是一个嵌套函数,它构建具有某种样式的拖放元素,拉入玩具数据

function App() {
    const [columns, setColumns] = useState(clusterColumns);
    return (
        <div>
            <div style={{display: 'flex', justifyContent: 'left', height: '95%', position: "relative",
                top: 5, left: 90, opacity: '27%'}}>
                <DragDropContext onDragEnd={result => onDragEnd(result, columns, setColumns)}>
                    {Object.entries(columns).map(([id, column]) => {
                        return (
                            <div style={{display: 'flex', flexDirection: 'column', alignItems:'center',
                                fontFamily: 'Montez, sans-serif', color: '#913aff', fontSize: 27, padding:5, borderRadius: '19px',
                            }}><h2  style={{fontSize:(19*3), height: 45}}>{column.name}</h2>
                                <h2  style={{fontSize:(19*3), height: 45, top:'9px', position:'absolute', opacity:'60%', color:'#ffa0f9'}}>{column.name}</h2>
                                <div style={{margin: 2}}>
                                    <Droppable droppableId={id} key={id} >
                                        {(provided, snapshot) => {
                                            return (
                                                <div {...provided.droppableProps}
                                                     ref={provided.innerRef}
                                                     style={{
                                                         padding: 9,
                                                         width: 190,
                                                         minHeight: 9,
                                                         opacity: '95%',
                                                         borderRadius: '9px',
                                                         background: 'linear-gradient(to right bottom, rgba(196, 181, 255, 1), rgba(132,47,0,0.27)'}} >
                                                         {column.items.map((item, index) => {
                                                            return (
                                                                <Draggable key={item.id} draggableId={item.id} index={index}>
                                                                    {(provided, snapshot) => {
                                                                        return (
                                                                            <div
                                                                                ref={provided.innerRef}
                                                                                {...provided.draggableProps}
                                                                                {...provided.dragHandleProps}
                                                                                style={{
                                                                                    opacity: '95%',
                                                                                    userSelect: 'none',
                                                                                    padding: 19,
                                                                                    margin: '0px 0px 3px 0px',
                                                                                    backgroundColor: snapshot.isDragging ? '#54ffff':'#b3f542',
                                                                                    background: 'linear-gradient(to right bottom, rgba(84, 255, 255, 0.63), rgba(179, 245, 66, 0.81)',
                                                                                    color: 'rgb(115,38,0)' ,
                                                                                    fontFamily: 'Montez',
                                                                                    fontSize: 36,
                                                                                    borderRadius: '9px',
                                                                                    ...provided.draggableProps.style
                                                                                }}>
                                                                                {item.content}
                                                                            </div>
                                                                        )
                                                                    }}
                                                                </Draggable>
                                                            )
                                                        }
                                                    )}
                                                    {provided.placeholder}
                                                </div>
                                            )
                                        }}
                                    </Droppable>
                                </div>
                            </div>
                        )
                    })}
                </DragDropContext>
            </div>
        </div>
    );
}

我的问题是,我可以构建什么,用用户输入新数据的按钮替换玩具数据,然后该按钮可能会出现在屏幕上?我尝试放置第二个程序,用于添加单元格。

class Cell extends React.Component {
    render() {
        return (
            <form>

                <input
                    type="text" style={{
                        display:'flex',
                    position:'relative',
                        top: '-360px',
                    right:'95px',
                    fontFamily: "VT323",
                    width:'144px',
                    fontSize:'36px',
                    color: 'rgb(115,38,0)',
                    opacity:'60%',
                    borderRadius: '9px',
                    height: '45px',
                    background: 'radial-gradient(rgba(196, 181, 255, .9), rgba(168,255,0,0.19)',
                    borderColor: 'rgba(255,255,255,0)'
                }}
                />
            </form>
        );
    }
}

但它是一个简单的用户表单;输入的数据应有效替换填充第一个程序顶部常量的玩具数据。

最佳答案

添加非常基本的输入以添加新项目的示例

为您的输入字段创建一个组件

function AddBookItem({ onAdd }) {
    const [value, setValue] = useState('');
    const onChange = ({ target: { value }}) => setValue(value);
    return (
        <div>
            <input value={value} onChange={onChange} placeholder="Book Item" />
            <button onClick={onAdd(value)}>Add book item</button>
        </div>
    );
}

创建一个函数来处理向父状态添加值

const onAdd = (value) => () => {
        setColumns((columns) => {
            const nC = {...columns};
            // get first book id
            const id = clusterKeys[0];
            const c = { ...columns[id] }
            // console.log({ c });
            const ci = [...c.items];
            ci.push({ id: uuid(), content: value });
            c.items = ci;
            nC[id] = c;
            return nC;
        })
    }

将新组件添加到您的应用

<AddBookItem onAdd={onAdd} />

https://codesandbox.io/s/stackoverflow-add-example-kfk2e

关于javascript - 如何优化 React 模式以允许用户将新数据输入到状态中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60440153/

相关文章:

javascript - React Native 发布构建崩溃问题,但在调试时它工作正常

reactjs - 如何在我自己的主题中设置 MUI TreeItem 组件的样式?

c# - 如何从另一个线程更新 GUI?

javascript - 使用 Angular 指令动态注入(inject)可运行的 JavaScript

javascript - 如何检查 JWT token 有效性

javascript - CoreUI React 登录后重新路由无法正常工作

javascript - Apollo Query 组件如何使用它的自身值作为回调

security - 用户名是否区分大小写?

eclipse - 用户体验设计师需要编程知识吗?

Javascript异步如何等待不同数量的uploadTasks全部完成?