Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

104
Vistas
React State not updating properly

I'm building a text editor using React with Typescript. The component hierarchy looks like this: TextEditor -> Blocks -> Block -> ContentEditable.

The ContentEditable is an npm package https://www.npmjs.com/package/react-contenteditable.

What i want it to do

The behavior I'm after is similar to Medium or Notions text editor. When a user writes in a block and hits enter on their keyboard, a new block should be created after the current block.

What it does

The behavior right now is strange to me. If I press enter and add one block, it works fine. But if I press enter again it overrides the previous block instead of creating a new one. However, if I press enter and add a block, then puts the carrot (focusing) on the new block and press enter again, a new block is added after as expected.

Sandbox

Here is a sandbox with the complete code: https://codesandbox.io/s/texteditor-mxgbey?file=/src/components/Block.tsx:81-557

TextEditor

export default function TextEditor(props) {
  const [blocks, setBlocks] = useState([
    { id: "1", tag: "h1", html: "Title1" },
    { id: "2", tag: "p", html: "Some text" }
  ]);

  function handleAddBlock(id: string) {
    const index = blocks.findIndex((b) => b.id === id);
    let copiedBlocks = [...blocks];
    let newBlock = { id: nanoid(), tag: "p", html: "New block..." };
    copiedBlocks.splice(index + 1, 0, newBlock);
    setBlocks(copiedBlocks);
  }

  return <Blocks injectedBlocks={blocks} handleAddBlock={handleAddBlock} />;
}

Blocks

export default function Blocks(props) {
  const { injectedBlocks, handleAddBlock } = props;
  return (
    <>
      {injectedBlocks.map((b) => {
        return (
          <Block
            key={b.id}
            id={b.id}
            tag={b.tag}
            html={b.html}
            handleAddBlock={handleAddBlock}
          />
        );
      })}
    </>
  );
}

Block

export default function Block(props) {
  const { id, tag, html, handleAddBlock } = props;

  function handleChange(e: React.SyntheticEvent) {}
  function handleKeyDown(e: React.KeyboardEvent) {
    if (e.key === "Enter") {
      console.log("Enter pressed on: ", id);
      e.preventDefault();
      handleAddBlock(id);
    }
  }

  return (
    <ContentEditable
      tagName={tag}
      html={html}
      onChange={handleChange}
      onKeyDown={handleKeyDown}
    />
  );
}
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

State value not give the updated value while handleAddBlock function calls. So use like this,

 setBlocks((p) => {
      let copiedBlocks = [...p];
      let newBlock = { id: nanoid(), tag: "p", html: "New block..." };
      copiedBlocks.splice(index + 1, 0, newBlock);
      return copiedBlocks;
    });

This will gives the updated state value immediately.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda