Saya ingin membuat aplikasi reaksi mudah di mana apabila saya menekan enter pada blok, blok baharu akan muncul di bawah blok itu dan selebihnya di belakangnya akan berada di bawah blok baharu.
Tetapi apabila terdapat beberapa blok, apabila saya tekan enter pada blok sebelumnya, blok yang terakhir hilang.
Saya tidak faham. Bolehkah sesiapa menunjukkan kesilapan ini?
Berikut adalah beberapa kod dan gambar:
editablePage.tsx
import { useState } from "react"; import EditableBlock, { BlockType } from "../editableBlock"; export default function EditablePage() { const [blocks, setBlocks] = useState<BlockType[]>([ { tag: "h1", content: "Welcome", position: 0 }, ]); function addBlockHandler({ tag, position }: BlockType) { const nextPosition = position + 1; const newBlock: BlockType = { tag: tag, content: nextPosition.toString(), position: nextPosition, }; console.log(blocks); const blocksBeforeNew = blocks.slice(0, nextPosition); const blocksAfterNew = blocks.slice(nextPosition).map((block) => { const copy = { ...block }; copy.position += 1; return copy; }); const updatedBlocks = blocksBeforeNew .concat(newBlock) .concat(blocksAfterNew); setBlocks(updatedBlocks); } return ( <div> {blocks.map(({ tag, content, position }: BlockType) => { return ( <EditableBlock key={position} tag={tag} position={position} content={content} addBlock={addBlockHandler} /> ); })} </div> ); }
editableBlock.tsx
import { useState } from "react"; import ContentEditable, { ContentEditableEvent } from "react-contenteditable"; type TagType = "h1" | "h2" | "h3" | "p"; export interface BlockType { tag: TagType; content: string; position: number; } export interface EditableBlockProps extends BlockType { addBlock: (currentBlock: BlockType) => void; } export default function EditableBlock({ tag, content, position, addBlock, }: EditableBlockProps) { const [text, setText] = useState<string>(content); const handleChange = (evt: ContentEditableEvent) => { setText(evt.target.value); }; const handleKeyDown = (evt: React.KeyboardEvent<HTMLElement>) => { if (evt.key === "Enter") { evt.preventDefault(); addBlock({ tag, content, position }); } }; return ( <ContentEditable tagName={tag} html={text} onChange={handleChange} onKeyDown={handleKeyDown} /> ); }
Sebelum:
Selepas menekan Enter pada blok pertama:
Saya dapati ralat datang dari blok tetapi saya tidak faham mengapa ini berlaku.
Ini ialah isu yang diketahui untuk
react-contenteditable
, sila lihat lovasoa/react-contenteditable# 161:Dalam penyelesaian yang dicadangkan dalam soalan yang dipautkan, anda boleh mencuba ulasan ini, yang merupakan varian Legacy React Documentation > How to from
useCallback
:useCallback
Baca nilai yang kerap berubah