O valor do editor de texto desaparece no React Js

Sep 01 2020

Estou fazendo um acordeão simples e dentro de cada acordeão há um editor de texto.

Accordion.js

<div className="wrapper">
  {accordionData.map((item, index) => (
    <Accordion>
      <Heading>
        <div
          style={{ padding: "10px", cursor: "pointer" }}
          className="heading"
          onClick={() => toggleHandler(index)}
        >
          {toggleValue !== index ? `Expand` : `Shrink`}
        </div>
      </Heading>
      <Text>  {toggleValue === index && item.content && <EditorContainer />} </Text>
    </Accordion>
  ))}
</div>

Aqui o acordeão é feito como um componente. Esta linha {toggleValue === index && item.content && <EditorContainer />} é feita para verificar o acordeão clicado e então carrega o conteúdo e o editor de texto de acordo.

Exemplo de trabalho completo:

https://codesandbox.io/s/react-accordion-forked-dcqbo

Etapas para reproduzir o problema:

-> Abra o link acima

-> Haverá três acordeão

-> Clique em qualquer um dos acordeões, que mudará o texto de Expandir para Diminuir

-> Agora preencha algum texto aleatório dentro do editor e clique no texto Reduzir

-> Abra novamente o mesmo acordeão clicando em Expandir

-> Agora falta o valor já inserido

Duvido que aconteça porque toda vez que expandimos / diminuímos, o componente text_editor.js é chamado e tem o valor de estado como,

this.state = {
  editorState: EditorState.createEmpty()
};

Aqui, em vez de EditorState.createEmpty (), devo informar mais alguma coisa?

Requerimento:

Como posso armazenar o valor já inserido no editor de texto. Mesmo que o usuário clique em expandir / reduzir, o texto inserido precisa permanecer lá no editor.

Qualquer ajuda é muito apreciada.

Respostas

1 bertdida Sep 02 2020 at 03:53

Você está correto, o valor inserido está faltando porque você está desmontando o EditorContainercomponente quando ele é reduzido - que quando você o expande novamente, ele cria um novo editorStateque está vazio.

2 Soluções possíveis nas quais eu poderia pensar.

  1. Mova editorStatee onEditorStateChangepara o componente pai e passe para EditorContainer. Dessa forma, quando desmontarmos o EditorContainer, não perderemos o anterior editorStateporque está no Pai.

  2. Envolvemos nosso EditorContainerdentro de a dive aplicamos um displayestilo quando alternamos entre reduzir / expandir. Desta forma, estamos apenas ocultando o EditorContainernão desmontando para que statesele retenha.

Eu escolheria implementar a 2ª solução porque só precisamos fazer alterações em nosso Accordion.jsarquivo. De qualquer maneira, eu criaria um novo componente que trataria do item atual. Eu chamo isso NormalAccordionItem.

const NormalAccordionItem = ({ data }) => {
  const [show, setShow] = useState(false);

  function toggle() {
    setShow((prev) => !prev);
  }

  return (
    <Accordion>
      <Heading>
        <div
          style={{ padding: "10px", cursor: "pointer" }}
          className="heading"
          onClick={toggle}
        >
          {show ? "Shrink" : "Expand"}
        </div>
      </Heading>
      <Text>
        <div style={{ display: show ? "block" : "none" }}> // notice this
          <EditorContainer />
        </div>
      </Text>
    </Accordion>
  );
};

Então no nosso NormalAccordionvamos usar NormalAccordionItem.

const NormalAccordion = () => {
  return (
    <div className="wrapper">
      {accordionData.map((data) => (
        <NormalAccordionItem data={data} key={data.id} />
      ))}
    </div>
  );
};

É isso, confira a demonstração abaixo.

Editar Demonstração atualizada para expandir NormalAccordionItemuma de cada vez.