更新通过 props 传输的数组
Update array that is transmitted through props
标题可能有点含糊,但我会更好地解释:)
所以我有这个组件DraggableGameSlots.tsx
import React, { useState } from "react";
import DraggableGameSlot from "./DraggableGameSlot";
type DraggableGameSlotsProps = {
numberOfAnswers: number,
slotFor: string
}
function DraggableGameSlots(props: DraggableGameSlotsProps) {
const [answers, setAnswers] = useState<string[]>(Array<string>(props.numberOfAnswers).fill("Drop here"));
return (
<div className="draggable-game-slots">
{
answers.map((val, index) => (
<DraggableGameSlot
className={props.slotFor === "text" ? "draggable-game-slot-for-text" : "draggable-game-slot-for-image"}
key={index}
answers={answers}
setAnswers={setAnswers}
/>
))
}
</div>
);
}
export default DraggableGameSlots;
和DraggableGameSlot.tsx
import { useEffect, useRef } from 'react';
import { useDrop } from 'react-dnd';
import './css/DraggableGameSlot.css';
type DraggableGameSlotProps = {
className: string,
answers: any,
setAnswers: any
}
function DraggableGameSlot(props: DraggableGameSlotProps) {
const [{isOver}, drop] = useDrop(() => ({
accept: "image",
drop(item: {id: string}) {
props.setAnswers([...props.answers, item.id]);
console.log(props.answers);
},
collect: (monitor) => ({
isOver: !!monitor.isOver(),
})
}))
useEffect(() =>
console.log(props.answers)
);
return (
<div className={`draggable-game-slot ${props.className}`} ref={drop}>
<span>Drop here</span>
</div>
)
}
export default DraggableGameSlot;
逻辑如下:
我有一系列答案,我想使用 react-dnd 添加新答案。最初的答案是“拖放到这里”(因为它们没有定义,所以只会出现带有这段文字的槽 - 我稍后会实现这个逻辑)。
所以我有一个包含所有答案的数组。我渲染它们,一切都很好。
然后我有一个来自 react-dnd 的 useDrop 挂钩 - 它用于定义可拖动项目的放置目标。这也不是帖子的重点:)
我观察到使用 DraggableGameSlot 中的两个 console.logs,对于 numberOfAnswers = 4,当我放下答案并调用 drop 时,我的数组将是长度 = 4(初始)或长度 = 5。
我预计每次删除答案并调用 props.setAnswers 时,都会在数组末尾添加一个新答案。嗯,这样不行,其实每次都改第5项
例如
Drop here Drop here Drop here Drop here
I drag answer1:
Expectation: Drop here Drop here Drop here Drop here answer1
Behavior: Drop here Drop here Drop here Drop here answer1
OK
I drag answer2:
Expectation: Drop here Drop here Drop here Drop here answer1 answer2
Behavior: Drop here Drop here Drop here Drop here answer2
NOT OK
我怀疑这是因为 props.answers 没有更新。通过道具而不是参考传递它时,我可能会得到它的值的副本,所以当我调用 setAnswers 时,answers 数组仅在 DraggableGameSlots 中更新并且 props.answers 保持不变。
好吧,我不想那样。
为什么会这样,我怎样才能让它按我想要的方式工作? :)
当仔细观察useDrop时,它使用记忆(依赖数组)和空数组作为默认值。您应该添加可以更改的依赖项数组(answers
、setAnswers
等)作为 useDrop.
的第二个参数
标题可能有点含糊,但我会更好地解释:)
所以我有这个组件DraggableGameSlots.tsx
import React, { useState } from "react";
import DraggableGameSlot from "./DraggableGameSlot";
type DraggableGameSlotsProps = {
numberOfAnswers: number,
slotFor: string
}
function DraggableGameSlots(props: DraggableGameSlotsProps) {
const [answers, setAnswers] = useState<string[]>(Array<string>(props.numberOfAnswers).fill("Drop here"));
return (
<div className="draggable-game-slots">
{
answers.map((val, index) => (
<DraggableGameSlot
className={props.slotFor === "text" ? "draggable-game-slot-for-text" : "draggable-game-slot-for-image"}
key={index}
answers={answers}
setAnswers={setAnswers}
/>
))
}
</div>
);
}
export default DraggableGameSlots;
和DraggableGameSlot.tsx
import { useEffect, useRef } from 'react';
import { useDrop } from 'react-dnd';
import './css/DraggableGameSlot.css';
type DraggableGameSlotProps = {
className: string,
answers: any,
setAnswers: any
}
function DraggableGameSlot(props: DraggableGameSlotProps) {
const [{isOver}, drop] = useDrop(() => ({
accept: "image",
drop(item: {id: string}) {
props.setAnswers([...props.answers, item.id]);
console.log(props.answers);
},
collect: (monitor) => ({
isOver: !!monitor.isOver(),
})
}))
useEffect(() =>
console.log(props.answers)
);
return (
<div className={`draggable-game-slot ${props.className}`} ref={drop}>
<span>Drop here</span>
</div>
)
}
export default DraggableGameSlot;
逻辑如下:
我有一系列答案,我想使用 react-dnd 添加新答案。最初的答案是“拖放到这里”(因为它们没有定义,所以只会出现带有这段文字的槽 - 我稍后会实现这个逻辑)。
所以我有一个包含所有答案的数组。我渲染它们,一切都很好。
然后我有一个来自 react-dnd 的 useDrop 挂钩 - 它用于定义可拖动项目的放置目标。这也不是帖子的重点:)
我观察到使用 DraggableGameSlot 中的两个 console.logs,对于 numberOfAnswers = 4,当我放下答案并调用 drop 时,我的数组将是长度 = 4(初始)或长度 = 5。
我预计每次删除答案并调用 props.setAnswers 时,都会在数组末尾添加一个新答案。嗯,这样不行,其实每次都改第5项
例如
Drop here Drop here Drop here Drop here
I drag answer1:
Expectation: Drop here Drop here Drop here Drop here answer1
Behavior: Drop here Drop here Drop here Drop here answer1
OK
I drag answer2:
Expectation: Drop here Drop here Drop here Drop here answer1 answer2
Behavior: Drop here Drop here Drop here Drop here answer2
NOT OK
我怀疑这是因为 props.answers 没有更新。通过道具而不是参考传递它时,我可能会得到它的值的副本,所以当我调用 setAnswers 时,answers 数组仅在 DraggableGameSlots 中更新并且 props.answers 保持不变。
好吧,我不想那样。
为什么会这样,我怎样才能让它按我想要的方式工作? :)
当仔细观察useDrop时,它使用记忆(依赖数组)和空数组作为默认值。您应该添加可以更改的依赖项数组(answers
、setAnswers
等)作为 useDrop.