【问题标题】:How to access ReactQuill Ref when using dynamic import in NextJS?在 NextJS 中使用动态导入时如何访问 ReactQuill Ref?
【发布时间】:2020-06-12 22:37:48
【问题描述】:

我遇到了一个有趣的问题。我将 NextJS 用于其服务器端渲染功能,并使用 ReactQuill 作为我的富文本编辑器。为了解决 ReactQuill 与 DOM 的关系,我动态地导入它。但是,这带来了另一个问题,即当我尝试将 ref 附加到 ReactQuill 组件时,它被视为可加载组件而不是 ReactQuill 组件。我需要 ref 来自定义上传到富文本编辑器时如何处理图像。现在,ref 返回 current:null 而不是我可以使用 .getEditor() on 自定义图像处理的函数。

有人对我如何解决这个问题有任何想法吗?我尝试了引用转发,但它仍然将引用应用于可加载组件,而不是 React-Quill 组件。这是我的代码的快照。

const ReactQuill = dynamic(import('react-quill'), { ssr: false, loading: () => <p>Loading ...</p> }
);

const ForwardedRefComponent = React.forwardRef((props, ref) => {return (
    <ReactQuill {...props} forwardedRef={(el) => {ref = el;}} />
)})

class Create extends Component {
    constructor() {
        super();
        this.reactQuillRef = React.createRef();
    }

    imageHandler = () => {
         console.log(this.reactQuillRef); //this returns current:null, can't use getEditor() on it.
    }
    render() {
    const modules = {
      toolbar: {
          container:  [[{ 'header': [ 2, 3, false] }],
            ['bold', 'italic', 'underline', 'strike'],
            [{ 'list': 'ordered'}, { 'list': 'bullet' }],
            [{ 'script': 'sub'}, { 'script': 'super' }],
            ['link', 'image'],
            [{ 'indent': '-1'}, { 'indent': '+1' }],    
            [{ 'align': [] }],
            ['blockquote', 'code-block'],],
          handlers: {
             'image': this.imageHandler
          }
        }
     };
         return(
             <ForwardedRefComponent 
                value={this.state.text}
                onChange={this.handleChange}
                modules={modules}
                ref={this.reactQuillRef}/> //this.reactQuillRef is returning current:null instead of the ReactQuill function for me to use .getEditor() on
         )
    }
}

const mapStateToProps = state => ({
    tutorial: state.tutorial,
});

export default connect(
    mapStateToProps, {createTutorial}
)(Create);

【问题讨论】:

  • 您不应该将ref 设置为ReactQuill 而不是forwardedRef
  • @Agney 根据 React 文档,它应该是我创建的 ref 并希望稍后引用,所以 this.reactQuillRef (reactjs.org/docs/forwarding-refs.html) 如果您有任何其他预感,请告诉我!跨度>
  • 没关系,用包装组件解决!
  • @user3783615 如果你不介意,你能告诉我你是怎么解决这个问题的吗?

标签: node.js reactjs next.js quill react-quill


【解决方案1】:

在 NextJS 中,React.useRef 或 React.createRef 不适用于动态导入。

你应该替换

const ReactQuill = dynamic(import('react-quill'), { ssr: false, loading: () => <p>Loading ...</p> }
);

import ReactQuill from 'react-quill';

并在window 加载后渲染。

import ReactQuill from 'react-quill';
class Create extends Component {
    constructor() {
        super();
        this.reactQuillRef = React.createRef();
        this.state = {isWindowLoaded: false};
    }
    componentDidMount() {
        this.setState({...this.state, isWindowLoaded: true});
    }

    .........
    .........

   render(){
     return (
       <div>
         {this.isWindowLoaded && <ReactQuil {...this.props}/>}
       </div>
     )
   }

}

【讨论】:

    【解决方案2】:

    如果你想通过动态导入在 Next.js 中使用 ref

    你可以使用React.forwardRef API

    more info

    【讨论】:

      【解决方案3】:

      使用 onChange 并传递所有参数,这里有一个使用 editor.getHTML() 的示例

      
      import React, { Component } from 'react'
      import dynamic from 'next/dynamic'
      import { render } from 'react-dom'
      
      const QuillNoSSRWrapper = dynamic(import('react-quill'), {
        ssr: false,
        loading: () => <p>Loading ...</p>,
      })
      
      const modules = {
        toolbar: [
          [{ header: '1' }, { header: '2' }, { font: [] }],
          [{ size: [] }],
          ['bold', 'italic', 'underline', 'strike', 'blockquote'],
          [
            { list: 'ordered' },
            { list: 'bullet' },
            { indent: '-1' },
            { indent: '+1' },
          ],
          ['link', 'image', 'video'],
          ['clean'],
        ],
        clipboard: {
          // toggle to add extra line breaks when pasting HTML:
          matchVisual: false,
        },
      }
      /*
       * Quill editor formats
       * See https://quilljs.com/docs/formats/
       */
      const formats = [
        'header',
        'font',
        'size',
        'bold',
        'italic',
        'underline',
        'strike',
        'blockquote',
        'list',
        'bullet',
        'indent',
        'link',
        'image',
        'video',
      ]
      
      class BlogEditor extends Component {
        constructor(props) {
          super(props)
          this.state = { value: null } // You can also pass a Quill Delta here
          this.handleChange = this.handleChange.bind(this)
          this.editor = React.createRef()
        }
      
        handleChange = (content, delta, source, editor) => {
          this.setState({ value: editor.getHTML() })
        }
      
        render() {
          return (
            <>
              <div dangerouslySetInnerHTML={{ __html: this.state.value }} />
              <QuillNoSSRWrapper ref={this.editor} onChange={this.handleChange} modules={modules} formats={formats} theme="snow" />
              <QuillNoSSRWrapper value={this.state.value} modules={modules} formats={formats} theme="snow" />
            </>
          )
        }
      }
      export default BlogEditor
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-09-18
        • 2019-05-28
        • 1970-01-01
        • 2011-11-09
        • 1970-01-01
        • 1970-01-01
        • 2021-12-28
        • 1970-01-01
        相关资源
        最近更新 更多