Bagaimana untuk membetulkan ralat ini tentang keadaan dalam tindak balas?
P粉214176639
P粉214176639 2024-04-01 09:32:43
0
1
403

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.

P粉214176639
P粉214176639

membalas semua(1)
P粉557957970

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 useCallbackuseCallback Baca nilai yang kerap berubah :

const useRefCallback = (
  value: ((...args: T) => void) | undefined,
  deps?: React.DependencyList
): ((...args: T) => void) => {
  const ref = React.useRef(value);

  React.useEffect(() => {
    ref.current = value;
  }, deps ?? [value]);

  const result = React.useCallback((...args: T) => {
    ref.current?.(...args);
  }, []);

  return result;
};

// Usage
export function EditablePage() {
  // State, addBlockHandler function...

  const addBlock2 = useRefCallback(addBlockHandler);

  return (
    
{blocks.map(({ tag, content, position }: BlockType) => { return ( ); })}
); }
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan