最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to insertupload image (update entity and blocks) in Draft.js? - Stack Overflow

programmeradmin0浏览0评论

I am trying to insert image to Draft.js editor.

Based on my understanding, I need update entity by mergeData and blocks by mergeBlockData. (I am not sure)

Now I am trying to use mergeBlockData to insert a block.

mergeBlockData(
  contentState: ContentState,
  selectionState: SelectionState,
  blockData: Map<any, any>
): ContentState

Please read ment in the code.

import { Map } from 'immutable';

const selection = this.state.editorState.getSelection();
const contentState = this.state.editorState.getCurrentContent();

console.log(convertToRaw(contentState));  // for example, I have 3 blocks

const blockData = Map({ ov72: {  // here how to generate a random valid key?
  "key": "ov72",
  "text": " ",
  "type": "atomic",
  "depth": 0,
  "inlineStyleRanges": [],
  "entityRanges": [{
    "offset": 0,
    "length": 1,
    "key": 1
  }],
  "data": {}
}});
const newContentState = Modifier.mergeBlockData(contentState, selection, blockData);

console.log(convertToRaw(newContentState));  // here is wrong, still 3 blocks. Also original blocks have no change

const newEditorState = EditorState.push(this.state.editorState, newContentState);

I am trying to insert image to Draft.js editor.

Based on my understanding, I need update entity by mergeData and blocks by mergeBlockData. (I am not sure)

Now I am trying to use mergeBlockData to insert a block.

mergeBlockData(
  contentState: ContentState,
  selectionState: SelectionState,
  blockData: Map<any, any>
): ContentState

Please read ment in the code.

import { Map } from 'immutable';

const selection = this.state.editorState.getSelection();
const contentState = this.state.editorState.getCurrentContent();

console.log(convertToRaw(contentState));  // for example, I have 3 blocks

const blockData = Map({ ov72: {  // here how to generate a random valid key?
  "key": "ov72",
  "text": " ",
  "type": "atomic",
  "depth": 0,
  "inlineStyleRanges": [],
  "entityRanges": [{
    "offset": 0,
    "length": 1,
    "key": 1
  }],
  "data": {}
}});
const newContentState = Modifier.mergeBlockData(contentState, selection, blockData);

console.log(convertToRaw(newContentState));  // here is wrong, still 3 blocks. Also original blocks have no change

const newEditorState = EditorState.push(this.state.editorState, newContentState);
Share Improve this question edited Dec 3, 2017 at 1:27 Hongbo Miao asked Dec 2, 2017 at 3:57 Hongbo MiaoHongbo Miao 50.2k67 gold badges200 silver badges328 bronze badges 4
  • You are merging blockData why would the size of blocks increase? – Nandu Kalidindi Commented Dec 2, 2017 at 23:44
  • @NanduKalidindi assume mergeBlockData is neither replace or add, what is the function of it? And which correct API should I use? – Hongbo Miao Commented Dec 2, 2017 at 23:46
  • I am working on a snippet. But I guess you should use ContentBlock if you want to add new blocks. – Nandu Kalidindi Commented Dec 2, 2017 at 23:48
  • @NanduKalidindi would u mind adding a demo for how to use ContentBlock to add new block in answer? thanks – Hongbo Miao Commented Dec 2, 2017 at 23:54
Add a ment  | 

3 Answers 3

Reset to default 6

Took a while to figure out how to insert image.

  insertImage = (editorState, base64) => {
    const contentState = editorState.getCurrentContent();
    const contentStateWithEntity = contentState.createEntity(
      'image',
      'IMMUTABLE',
      { src: base64 },
    );
    const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
    const newEditorState = EditorState.set(
      editorState,
      { currentContent: contentStateWithEntity },
    );
    return AtomicBlockUtils.insertAtomicBlock(newEditorState, entityKey, ' ');
  };

Then you can use

const base64 = 'aValidBase64String';
const newEditorState = this.insertImage(this.state.editorState, base64);
this.setState({ editorState: newEditorState });

For render image, you can use Draft.js image plugin.

Live demo: codesandbox

The demo inserts a Twitter logo image.


If you want to insert a image from local file, you can try to use FileReader API to get that base64.

For how to get base64, it is simple, check

Live demo: jsbin

Now go ahead to put them together, you can upload image from local file!

If you are using draft-js image plugin, you can achieve this as follows.

Get the base64 of your image as @Hongbo Miao explained.

const imagePlugin = createImagePlugin();//initialize image plugin
const base64 = 'aValidBase64String';
const newEditorState = imagePlugin.addImage(this.state.editorState, base64);
this.setState({ editorState: newEditorState });

If you want to insert a new Block then you probably would want to use ContentBlock and not mergeBlockData.

ContentBlock: https://draftjs/docs/api-reference-content-block.html#content

Please give this snippet a try.

import { genKey } from 'draft-js'

addNewBlock(editorState) {
  const text = 'Alpha';
  const block = new ContentBlock({
    key: genKey(),
    type: 'unstyled',
    text,
  });

  const contentState = editorState.getCurrentContent();
  const blockMap = contentState.getBlockMap().set(block.key, block);                   

  return EditorState.push(editorState, contentState.set('blockMap', blockMap));
}
发布评论

评论列表(0)

  1. 暂无评论