😱
collision detection을 꺼보니 각도가 다시 계산되는 것을 발견하고 문제 해결의 실마리를 잡았다
우선 이 문제는 해결했다. 어떻게 해결했냐!! contextProvider에서 데이터의 위치를 계산해서 data초기값으로 설정해놓았는데 이게 data가 변경될때마다 Provider 함수가 불려지며 initializeNodePosition이 계속 호출되고 그것 때문에 위치들이 변경되는 거였다. 그래서 Provider안에서 initializeNodePosition(data)로 넣는 것이 아니라 Provider 바깥에서 계산을 하고 useState에 담아서 사용하는 방식으로 바꿔 해결하였습니다.
Provider{
const [data, setData] = useState(initializeNodePosition(data));
}
해당 문제는 아마도 라이브러리 상의 문제인 것으로 보인다.
react-konva가 제공하는 캔버스의 각 요소들은 얼핏 보면 jsx element로 착각할 수 있지만, 타입을 보면 KonvaNodeComponent
로 되어있다. 이는 우리가 평소에 사용하던 jsx element처럼 사용한다 해도 이와 동일한 효과를 낼 수 있는 확률이 무조건적으로 보장되어있지는 않다는 의미기도 하다.
export default function EditableText({
id,
text,
isEditing,
setIsEditing,
offsetX,
offsetY,
width,
}: EditableTextProps) {
const originalContent = text;
const [content, setContent] = useState(originalContent);
const { data, updateNode } = useNodeListContext();
useEffect(() => {
setContent(text);
}, [text]);
function handleTextChange(e: React.ChangeEvent<HTMLInputElement>) {
setContent(e.target.value);
}
function saveContent() {
if (content.trim()) updateNode(id, { ...data[id], keyword: content });
else setContent(originalContent);
setIsEditing(false);
}
function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
if (e.key === "Enter") saveContent();
}
function handleBlur() {
saveContent();
}
return (
<>
{isEditing ? (
<EditableTextInput
value={content}
onChange={handleTextChange}
onKeyDown={handleKeyDown}
onBlur={handleBlur}
offsetX={offsetX}
offsetY={offsetY}
width={width}
/>
) : (
<Text
text={content}
fill="black"
wrap="word"
align="center"
fontStyle="bold"
offsetX={offsetX}
offsetY={offsetY}
width={width}
/>
)}
</>
);
}
문제의 코드는 이 곳이다.
텍스트가 비었을 때 되돌리기 위해서 originalText라는 변수를 따로 할당해놓았고, 해당 원시값을 useState에 넣어 상태로 관리하면서 input을 관리할 수 있도록 하였다.
하지만 data들이 바뀌면서 다시금 렌더링이 되는 타이밍에서 요소들의 text가 삭제한 요소들의 텍스트로 바뀌는 문제가 생겼다.
상태는 따로 변경 없이 들고 있었는데, 갑자기 기존의 데이터가 바뀌면서 이를 제대로 인지하지 못한 채, 마치 데이터가 하나씩 밀려나가는 현상을 보여주었다. 이에 대해서 여러가지 추측을 해 보았는데,
등등…
아마 현재는 2번이라고 생각한다. 이에 대해서는 더 알아볼 필요가 있을 것 같다.