facebookarchive / draft-js

A React framework for building text editors.
https://draftjs.org/
MIT License
22.57k stars 2.64k forks source link

setBlockData and mergeBlockData should accept non-Immutable objects #2245

Open tamias opened 4 years ago

tamias commented 4 years ago

Do you want to request a feature or report a bug? Feature

What is the current behavior? Calling setBlockData or mergeBlockData requires passing an Immutable Map as the third argument, which forces the calling package to have a direct dependency on Immutable.

What is the expected behavior? setBlockData and mergeBlockData should accept either an Immutable map or a plain object which it converts to a Map internally.

Which versions of Draft.js, and which browser / OS are affected by this issue? Did this work in previous versions of Draft.js? 0.11.1

We are in the process of replacing Immutable with Immer in our repo. However, in order to use setBlockData, we have to create an Immutable Map and pass it into the method, which means we can't completely remove our direct dependency on Immutable. That wouldn't be an issue if we could pass in a plain object instead.

folkjc commented 4 years ago

If you don't want direct dependency on immutable, you can create an empty object using the Draft API, and get a clean Map from there.

ie.

const tempContentBlock = new ContentBlock({ data: { } });
const blankImmutableMap = tempContentBlock.getData(); //returns immutable map. i think. 
const updatedImmutableMap = blankImmutableMap.merge({ hello: 2 })

A little hacky, but gets the job done. If you don't want to do it every time, you can also create your own function:

const convertObjectToImmutableMap = raw => {
    const tempContentBlock = new ContentBlock();
    const blankImmutableMap = tempContentBlock.getData(); //returns immutable map. i think. 
    const updatedImmutableMap = blankImmutableMap.merge(raw)
    return updatedImmutableMap
}
tamias commented 4 years ago

Thank you for the suggestion! I tried it out, and it works well.

I also thought of another solution, which is to simply import from draft-js's immutable, e.g.: import { Map } from 'draft-js/node_modules/immutable'; It's hacky in its own way, but works as well.

Either way, I'm all set, so feel free to close this ticket.