首页  >  问答  >  正文

如何修复react中关于状态的这个错误?

我想做一个简单的反应应用程序,当我在一个块上按回车键时,一个新块将显示在该块下,而后面的其余部分将在新块下。

但是当有多个块时,当我在前一个块上按回车键时,后一个块就会消失。

我不明白。有人能指出这个错误吗?

以下是一些代码和图片:

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}
    />
  );
}

之前:

在第一个块上按 Enter 键后:

我发现该错误来自块,但我不明白为什么会发生这种情况。

P粉214176639P粉214176639226 天前396

全部回复(1)我来回复

  • P粉557957970

    P粉5579579702024-04-02 08:08:07

    这是 react-contenteditable 的已知问题,请参阅 lovasoa/react-contenteditable# 161:

    在链接问题中提出的解决方法中,您可以尝试 该评论,它是 useEventCallback 的变体every-change-value-from-usecallback" rel="nofollow noreferrer">遗留 React 文档 > 如何从 useCallback 读取经常变化的值?:

    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 ( ); })}
    ); }

    回复
    0
  • 取消回复