Reactjs - CKEditor onchange 提升状态

Reactjs - CKEditor onchange lift up state

我设法设置了 CKEditor,它运行良好。我的问题是我正在重构代码,我需要编辑器组件被其他几个组件调用。

所以,我的 handleChange 不再有效了。我怎样才能只将数据传递给 parent 的 handleChange 函数?

parent:

function IncluirArtigo() {

    const campos = { autor: '', titulo: '', texto: '' };

    const [valores, setValores] = useState(campos);
    const [erro, setErro] = useState(false);
    const history = useHistory();

    const handleChange = e => {
        setValores({
            ...valores,
            [e.target.name]: e.target.value
        });
        console.log(valores)
    }

    const incluir = async (e) => {
        e.preventDefault();

        console.log(valores);
        
        try {
            //await PostArtigo(valores);
            /* Poderia redirecionar para o artigo criado, se o post retornasse uma id */
            goHome();
        }
        catch (e) {
            console.error('erro', e);
            setErro(true);
        }
    }

    const goHome = () => history.push('/');

    return (
        <div className="container">
            {
                erro ?
                    <div>Houve erro na inclusão do artigo, tente novamente</div>
                    :
                    <>
                        <h3>Inclusão de Artigos</h3>
                        <form onSubmit={incluir} className="form-incluir">
                            <label htmlFor="autor">Autor:</label>
                            <input 
                                type="text" 
                                name="autor" 
                                value={valores.autor}
                                onChange={handleChange}
                            />
                            <label htmlFor="titulo">Título:</label>
                            <input 
                                type="text" 
                                name="titulo" 
                                value={valores.titulo}
                                onChange={handleChange}    
                                />
                            <label>Conteúdo:</label>
                            <div className="editor">
                                <Editor />
                            </div>
                            <input className="btn-enviar" type="submit" value="Enviar" />
                        </form>
                    </>
            }
        </div >
    )
}

editor.js

function Editor() {

    return (
        <div className="editor">
            <CKEditor
                editor={ClassicEditor}
                data={valores.texto}
                onChange={(event, editor) => {
                    const texto = editor.getData();
                    console.log({ event, editor, texto });
                    handleChange() /* I need this function to pass only valores data */
                }}
            />
        </div>
    )
}

方法一:家长控制文本

我们可以通过从父级向下传递值并使用 onChange 回调来更新父级中的值,使编辑器成为受控组件。

function Editor({ texto, onChangeTexto }) {
  return (
    <div className="editor">
      <CKEditor
        editor={ClassicEditor}
        data={texto}
        onChange={(event, editor) => {
          onChangeTexto(editor.getData());
        }}
      />
    </div>
  );
}
<Editor
  texto={valores.texto}
  onChangeTexto={(texto) => {
    setValores({ ...valores, texto });
  }}
/>

方法二:父级访问编辑器实例

CKEditor 组件有一个名为 onInit 的道具,我们可以使用它来将对 editor 对象的引用传递给父级。父级可以从 editor.getData() 而不是 valores.texto.

获取文本的值,而不是在每次更改时更新状态
function Editor({ onInit }) {
  return (
    <div className="editor">
      <CKEditor
        editor={ClassicEditor}
        onInit={onInit}
      />
    </div>
  );
}

父级:

const [editor, setEditor] = useState(null);
<Editor
  onInit={setEditor}
/>

获取文本(在提交功能中)

const texto = editor?.getData();

在这种特殊情况下,我可能会使用方法 2,因为它限制了状态更改的数量并且 re-renders。