【问题标题】:How to integrate react-draft-wysiwyg custom component with React-Final-Form如何将 react-draft-wysiwyg 自定义组件与 React-Final-Form 集成
【发布时间】:2020-02-17 17:46:22
【问题描述】:

我正在尝试学习如何使用 React-Final-Form(简称 RFF)。

我已经学会了如何使用<Field> 组件,但现在我需要添加一个自定义组件来使用 RFF 不提供的 WYSIWYG 编辑器。

所以,我选择了 react-draft-wysiwyg。

好的,首先这里是我的表单:

const FormComponent = () => {

  const handleSubmitOnClick = () => ({
    news_title,
    news_subtitle,
    editor_content, 
    image_url,
  }) => {

    const data = {
      "user": {
        news_title: news_title,
        news_subtitle: news_subtitle,
        editor_content: editor_content <- here the content from the WYSIWYG editor
        image_url: image_url 
      }
    }

     // API call here .... 
  }

  return (
    <>
      <h1>News Main Page</h1>

      <Form 
        onSubmit={handleSubmitOnClick()}
      >
        {
          ({ 
            handleSubmit, 
            values, 
            submitting,
          }) => (
          <form onSubmit={handleSubmit} data-testid="form">
            <Field 
              name='news_title'
              placeholder='News Title'
              validate={required}
            >
              {({ input, meta, placeholder }) => (
                <div className={meta.active ? 'active' : ''}>

                  <input {...input} 
                    type='text' 
                    placeholder={placeholder} 

                  />
                </div>
              )}
            </Field>

            <Field 
              name='news_subtitle'
              placeholder='News SubTitle'
              validate={required}
            >
              {({ input, meta, placeholder }) => (
                <div className={meta.active ? 'active' : ''}>

                  <input {...input} 
                    type='text' 
                    placeholder={placeholder} 
                  />
                </div>
              )}
            </Field>


            <WYSIWYGEditor /> **** HERE THE ISSUE ****

            <MyDropzone />
            <button 
              type="submit"
              className="signup-button"
              disabled={submitting}
            >
              Continue
            </button>

          </form>
        )}
      </Form>
    </>
  )
}

export default FormComponent;

这是编辑器文件:

import React, { useState } from 'react';

// Components
import { EditorState, convertToRaw } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import draftToHtml from 'draftjs-to-html';


// Hooks version of the Class below (done by me)
const WYSIWYGEditor = () => {
  const [editorState, setEditorState] = useState(EditorState.createEmpty());
  const onEditorStateChange = editorState => {
    return setEditorState(editorState)
  } 

  return (
    <div className="editor">
      <Editor 
        editorState={editorState} 
        wrapperClassName="demo-wrapper"
        editorClassName="demo-editor"
        onEditorStateChange={onEditorStateChange}
      />
      {
        console.log('editorState => ', draftToHtml(convertToRaw(editorState.getCurrentContent())))
      }
    </div>
  )
}

export default WYSIWYGEditor

&lt;WYSIWYGEditor /&gt; 返回正确的值,没有问题,但我不知道如何使用name='editor_content' 和单击表单submit 按钮时将此组件集成到RFF 流中。

非常感谢任何帮助。

【问题讨论】:

    标签: reactjs react-final-form react-draft-wysiwyg


    【解决方案1】:

    好的,我自己通过查看 React-Final-Form 网站找到了解决方案。

    为了在您的 RFF 表单中使用带有&lt;Field&gt; 的自定义解决方案或第 3 方组件,您需要添加以下内容:

    // RFF形式的主组件文件

    ....
    
    <Field
      name="editor_content"
      component={WYSIWYGEditor}
    />
    
    etc...
    

    请注意:不要尝试以这种方式传递组件component={&lt;WYSIWYGEditor /&gt;},否则会返回关于不允许传递对象的错误 不要忘记导入组件:)

    上面的例子会将inputmeta传递给自定义组件来收集数据并在表单中使用,方法如下:

    //所见即所得编辑器文件

    const WYSIWYGEditor = ({ input, meta }) => {
      const [editorState, setEditorState] = useState(EditorState.createEmpty());
      const onEditorStateChange = editorState => {
        setEditorState(editorState)
        return input.onChange(draftToHtml(convertToRaw(editorState.getCurrentContent())))
    
    etc....
      } 
    

    您会注意到,在 onEditorStateChange 函数中,我已经能够使用道具中的 input,并且通过使用 onChange 方法,我可以将返回的值传回给父组件(RFF 形式)。

    我希望这对其他人有所帮助。 编码愉快!

    【讨论】:

    • 干得好。供将来参考:RFF 维护“受控”输入所需的唯一约定是输入接受当前的value 和一个在值更改时调用的onChange 回调。
    • @ErikR。谢谢你的评论。您能否在您的 cmets 中提供重构代码的 sn-p?非常感谢。
    • 嗯?您说您“找到了解决方案”。不知道你在问什么。
    • @ErikR。它已修复,我只是想知道您的评论是否建议进行一些重构以使代码更好。只是。不用担心。
    • @Joe 如何使用htmlToDraft 设置初始值?
    【解决方案2】:

    这非常有帮助。如果不是 etc.... 你会放入完整版本的代码或接近它,它会更有帮助。我最终得到了这个:

    import * as React from 'react';
    import { useState } from 'react';
    import { EditorState, convertToRaw } from 'draft-js';
    import { Editor } from 'react-draft-wysiwyg';
    
    // Hooks version of the Class below (done by me)
    const WYSIWYGEditor = ({ input, meta }) => {
        const [editorState, setEditorState] = useState(EditorState.createEmpty());
        const onEditorStateChange = editorState => {
            setEditorState(editorState)
            return input.onChange(convertToRaw(editorState.getCurrentContent()))
        }
    
        return (
            <div className="editor">
                <Editor 
                editorState={editorState} 
                wrapperClassName="demo-wrapper"
                editorClassName="demo-editor"
                onEditorStateChange={onEditorStateChange}
                />
                {
                    console.log('editorState => ', convertToRaw(editorState.getCurrentContent()))
                }
            </div>
        )
    }
    
    export default WYSIWYGEditor;
    

    【讨论】:

    • 太棒了!如果我有initialValues 怎么办?我怎么能把它传进去?
    猜你喜欢
    • 1970-01-01
    • 2020-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    相关资源
    最近更新 更多