首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在功能组件中使用DraftJS

在功能组件中使用DraftJS
EN

Stack Overflow用户
提问于 2022-04-03 21:23:53
回答 2查看 1.1K关注 0票数 4

我试图在现有的功能组件中实现DraftJS,但我无法弄清楚如何做到这一点。看来,所有文档和用户提交的内容都涉及到类组件。

我尝试使用以下方法来设置它:

代码语言:javascript
复制
import { Editor } from "react-draft-wysiwyg";
import { EditorState } from 'draft-js'

export default function myFunctionalComponent() {

    const [editorState, setEditorState] = useState(EditorState.createEmpty())

    return(
        <Editor 
            editorState={editorState}
            onChange={setEditorState}
        />
    )
}

然而,不幸的是,我在控制台中得到了这个错误:

警告:无法对尚未挂载的组件调用setState。这是一个非操作,但它可能表明您的应用程序中有错误。相反,直接分配给this.state,或者在r组件中定义一个具有所需状态的state = {};类属性。

是否有一种方法可以在一个功能组件中工作?

EN

回答 2

Stack Overflow用户

发布于 2022-05-27 06:38:55

我能够用React钩子解决这个问题,而且它对我很有用。

代码语言:javascript
复制
import { EditorState } from 'draft-js'

export default function myFunctionalComponent() {

    const [editorState, setEditorState] = useState(EditorState.createEmpty())

     const onEditorStateChange = useCallback(
     (rawcontent) => {
       setEditorState(rawcontent.blocks[0].text);
     },
     [editorState]
   ); 
    return(
          <Editor
          placeholder="Tell a story..."
          onChange={onEditorStateChange}
        />
    )
}
票数 2
EN

Stack Overflow用户

发布于 2022-09-12 15:41:52

这是我在StackOverflow上的第一个答案。:)

我以https://github.com/facebook/draft-js/blob/main/examples/draft-0-10-0/rich/rich.html中的例子为例,将其转换为一个功能组件'RTEditor‘。。

使用带有setContent的组件作为支柱。它使用函数从useState更新父元素状态。

代码语言:javascript
复制
    const [content, setContent] = useState<any>({})
    ...
    <RTEditor setContent={setContent} />

RTEditor.tsx

代码语言:javascript
复制
    import React, { useState, useRef } from 'react'
    
    import {
      Editor,
      EditorState,
      RichUtils,
      getDefaultKeyBinding,
      ContentBlock,
      DraftHandleValue,
      convertFromHTML,
      convertFromRaw,
      convertToRaw,
      ContentState,
      RawDraftContentState,
    } from 'draft-js'
    import 'draft-js/dist/Draft.css'
    
    import BlockStyleControls from './BlockStyleControls'
    import InlineStyleControls from './InlineStyleControls'
    
    type Props = {
      setContent: (state: RawDraftContentState) => void
    }
    
    const RTEditor = ({ setContent }: Props) => {
      const editorRef = useRef(null)
      const [editorState, setEditorState] = useState(EditorState.createEmpty())
    
      const styleMap = {
        CODE: {
          backgroundColor: 'rgba(0, 0, 0, 0.05)',
          fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace',
          fontSize: 16,
          padding: 2,
        },
      }
    
      const getBlockStyle = (block: ContentBlock) => {
        switch (block.getType()) {
          case 'blockquote':
            return 'RichEditor-blockquote'
          default:
            return ''
        }
      }
    
      const onChange = (state: EditorState) => {
        setEditorState(state)
        setContent(convertToRaw(editorState.getCurrentContent()))
      }
    
      const mapKeyToEditorCommand = (e: any): string | null => {
        if (e.keyCode === 9 /* TAB */) {
          const newEditorState = RichUtils.onTab(e, editorState, 4 /* maxDepth */)
          if (newEditorState !== editorState) {
            onChange(newEditorState)
          }
          return null
        }
        return getDefaultKeyBinding(e)
      }
    
      const handleKeyCommand = (
        command: string,
        editorState: EditorState,
        eventTimeStamp: number
      ): DraftHandleValue => {
        const newState = RichUtils.handleKeyCommand(editorState, command)
        if (newState) {
          onChange(newState)
          return 'handled'
        }
        return 'not-handled'
      }
    
      const toggleBlockType = (blockType: string) => {
        onChange(RichUtils.toggleBlockType(editorState, blockType))
      }
    
      const toggleInlineStyle = (inlineStyle: string) => {
        onChange(RichUtils.toggleInlineStyle(editorState, inlineStyle))
      }
    
      return (
        <>
          <BlockStyleControls
            editorState={editorState}
            onToggle={toggleBlockType}
          />
          <InlineStyleControls
            editorState={editorState}
            onToggle={toggleInlineStyle}
          />
          <Editor
            ref={editorRef}
            editorState={editorState}
            placeholder='Tell a story...'
            customStyleMap={styleMap}
            blockStyleFn={(block: ContentBlock) => getBlockStyle(block)}
            keyBindingFn={(e) => mapKeyToEditorCommand(e)}
            onChange={onChange}
            spellCheck={true}
            handleKeyCommand={handleKeyCommand}
          />
        </>
      )
    }
    
    export default React.memo(RTEditor)

BlockStyleControls.tsx

代码语言:javascript
复制
    import React from 'react'
    import { EditorState } from 'draft-js'
    
    import StyleButton from './StyleButton'
    
    const BLOCK_TYPES = [
      { label: 'H1', style: 'header-one' },
      { label: 'H2', style: 'header-two' },
      { label: 'H3', style: 'header-three' },
      { label: 'H4', style: 'header-four' },
      { label: 'H5', style: 'header-five' },
      { label: 'H6', style: 'header-six' },
      { label: 'Blockquote', style: 'blockquote' },
      { label: 'UL', style: 'unordered-list-item' },
      { label: 'OL', style: 'ordered-list-item' },
      { label: 'Code Block', style: 'code-block' },
    ]
    
    type Props = {
      editorState: EditorState
      onToggle: (bockType: string) => void
    }
    
    const BlockStyleControls = ({ editorState, onToggle }: Props) => {
      const selection = editorState.getSelection()
      const blockType = editorState
        .getCurrentContent()
        .getBlockForKey(selection.getStartKey())
        .getType()
    
      return (
        <div className='RichEditor-controls'>
          {BLOCK_TYPES.map((type) => (
            <StyleButton
              key={type.label}
              active={type.style === blockType}
              label={type.label}
              onToggle={onToggle}
              style={type.style}
            />
          ))}
        </div>
      )
    }
    
    export default React.memo(BlockStyleControls)

InlineStyleControls.tsx

代码语言:javascript
复制
    import React from 'react'
    import { EditorState } from 'draft-js'
    
    import StyleButton from './StyleButton'
    
    const INLINE_STYLES = [
      { label: 'Bold', style: 'BOLD' },
      { label: 'Italic', style: 'ITALIC' },
      { label: 'Underline', style: 'UNDERLINE' },
      { label: 'Monospace', style: 'CODE' },
    ]
    
    type Props = {
      editorState: EditorState
      onToggle: (bockType: string) => void
    }
    
    const InlineStyleControls = ({ editorState, onToggle }: Props) => {
      const currentStyle = editorState.getCurrentInlineStyle()
    
      return (
        <div className='RichEditor-controls'>
          {INLINE_STYLES.map((type) => (
            <StyleButton
              key={type.label}
              active={currentStyle.has(type.style)}
              label={type.label}
              onToggle={onToggle}
              style={type.style}
            />
          ))}
        </div>
      )
    }
    
    export default React.memo(InlineStyleControls)

StyleButton.tsx

代码语言:javascript
复制
    import React from 'react'
    
    type Props = {
      active: boolean
      style: string
      label: string
      onToggle: (bockType: string) => void
    }
    
    const StyleButton = ({ active, style, label, onToggle }: Props) => {
      const _onToggle = (e: any) => {
        e.preventDefault()
        onToggle(style)
      }
    
      const className = 'RichEditor-styleButton'
    
      return (
        <button
          className={className + `${active ? ' RichEditor-activeButton' : ''}`}
          onClick={_onToggle}
        >
          {label}
        </button>
      )
    }
    
    export default React.memo(StyleButton)

没有涵盖所有类型的Sry。希望这能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71729962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档