reactjs - NextJS React,UseState中的嵌套数组未在javascript内部更新时呈现
问题描述
我很难理解“useState”以及何时触发渲染。我想制作一个拖放系统,用户可以将元素从一个盒子拖到另一个盒子。
我已经通过使用纯 JavaScript 成功地做到了这一点,但像往常一样,它很快就会变得一团糟,我想保持干净。我想既然我正在使用反应,我应该使用 UseState 来完成,并且我已经让数组以我想要的方式更新,但更改不会呈现。
我不应该以这种方式使用 useState 吗?我应该改用什么?我不想以“hacky”的方式解决它,我希望它是正确的。
const [allComponents, updateArray] = useState([])
function arrayMove(array, closest) {
let moveChild = array[parentIndex].children[childIndex]
array[parentIndex].children = array[parentIndex].children.filter(function(value, index, arr){ return index != childIndex;});
array[closest].children = [...array[closest].children, moveChild];
return array;
}
var lastClosest = {"parent": null, "child": null};
var parentIndex = null;
var childIndex = null;
function allowDrop(ev, index) {
ev.preventDefault();
if(allComponents.length > 0) {
let closest = index;
if((parentIndex == lastClosest.parent && childIndex == lastClosest.child) || (closest == parentIndex)) {
return;
}
lastClosest.parent = parentIndex;
lastClosest.child = childIndex;
updateArray(prevItems => (arrayMove(prevItems, closest)));
}
}
function dragStart(pI, cI, ev) {
parentIndex = pI;
childIndex = cI;
}
function drop(ev) {
ev.preventDefault();
}
function addNewSpace() {
updateArray(prevItems => [...prevItems, {"name": "blaab", "children": [{"child": "sdaasd", "type": "text"}]}]);
}
return (
<div className={styles.container}>
<button onClick={addNewSpace}>Add</button>
<div className={styles.spacesWrapper}>
{allComponents.map(({name, children}, index) => (
<div key={"spacer_" + index} onDragOver={(event) => allowDrop(event, index)} onDrop={(event) => drop(event)} className={styles.space}>
{children.map(({type, child}, index2) => (
<div id ={"movable_" + index + ":" + index2} key={"movable_" + index2} className={styles.moveableOne}>
<div key={"draggable_" + index2} draggable="true" onDrag={(event) => onDrag(event)} onDragStart={(event) => dragStart(index, index2, event)}>
</div>
</div>
))}
</div>
))}
</div>
</div>
)
}
解决方案
尝试使用以下代码修改您的代码,看看它是否解决了您的问题,
import React, { useState, useEffect } from "react";
let newAllComponents = [...allComponents];
useEffect(() =>
{
newAllComponents = [...allComponents]
}, [allComponents]);
/* div inside return*/
{newAllComponents.map(({ name, children }, index) => (
<div
key={"spacer_" + index}
onDragOver={(event) => allowDrop(event, index)}
onDrop={(event) => drop(event)}
>
推荐阅读
- java - 反序列化自定义对象的序列化 ArrayList,添加对象,然后重新序列化
- python - 如何使用 python open-cv 获取图像名称
- bluetooth-lowenergy - createCharacteristic 具有 3 个或更多特性的 BLE 应用程序?
- testing - 在 JSON 测试用例中读取额外的属性或主机地址
- r - 在 ubuntu 16.04 中从终端运行 R 会给出致命错误消息
- notepad++ - Notepad++ 加入模式匹配后的行
- html - 使用 CSS @supports 查询 CSS env() 和 CSS 变量支持
- java - 为非泛型堆栈类编写方法如何工作?
- java - 检查在移动屏幕上滑动是否加载了新元素
- vb.net - 如何在 DataGridView 中获取实际行的高度?