updating entities fail to trigger render
steckel opened this issue ยท 8 comments
This seems to be a bug.
When updating the contentState of the Editor it is my understanding the child entity Components should be updated with new contentState prop. This does not seem to be happening.
The specific situation is that I am updating contentState with a new result from contentState.mergeEntityData
and subsequent Editor.push
.
In the following fiddle, I expect the activate and deactivate buttons to update the contentState, thus re-rendering the entity's TestComponent which should resort in the toggling of a blue or yellow background. You can verify the {active}
data triggers the background change by editing the initial rawData and verify that the contentState is updating with the "Log State" button.
https://jsfiddle.net/steckel/h9gd6bm0/
I am testing using Chrome 56.0.2924.87 and draft-js 0.10.0.
I agree, this is certainly annoying behavior!
The workaround that currently seems to be advised is to use EditorState.forceSelection
to force an update. In your fiddle, pressing a button and then clicking to change selection does cause {active}
to update.
For example, using forceSelection
as workaround might look like:
_handleActiveEntityClick = () => {
const entityKey = "1";
const contentState = this.state.editorState.getCurrentContent();
const entity = contentState.getEntity(entityKey);
const newContentState = contentState.replaceEntityData(entityKey, {active: true});
const editorState = EditorState.push(this.state.editorState, newContentState, "activate-entity-data");
const selection = editorState.getSelection();
this.setState({editorState: EditorState.forceSelection(editorState, selection)});
}
_handleDeactiveEntityClick = () => {
const entityKey = "1";
const contentState = this.state.editorState.getCurrentContent();
const entity = contentState.getEntity(entityKey);
const newContentState = contentState.replaceEntityData(entityKey, {active: false});
const editorState = EditorState.push(this.state.editorState, newContentState, "deactivate-entity-data");
const selection = editorState.getSelection();
this.setState({editorState: EditorState.forceSelection(editorState, selection)});
}
Anyway, I agree that this is undesirable and would ideally be handled better...
Thank you for the quick reply! Is it safe to consider this a bug or would that be an egregious term and this is just a misunderstanding of the design decisions?
@steckel I'm not sure! I personally feel like it is a bug -- but I also very well could just have a misunderstanding of the design decisions around this aspect of draft-js.
@steckel @kedromelon I would expect this to re-render properly:
const newContentState = contentState.mergeEntityData(
entityKey,
data
);
this.setState({editorState: EditorState.push(editorState, newContentState, 'apply-entity')});
I would argue that this is the expected behavior when you are dealing with immutable.js and react. Currently I need to do an applyEntity()
to get this to work:
let newContentState = contentState.mergeEntityData(
entityKey,
data
);
const selection = SelectionState.createEmpty(block.getKey()).set('focusOffset', 1);
newContentState = Modifier.applyEntity(
newContentState,
selection,
entityKey
);
this.setState({editorState: EditorState.push(editorState, newContentState, 'apply-entity')});
This seems like a hack.
As you can see in the current code 0.10 doesn't even try to provide an immutable api for entities. The same method in 0.11-alpha handles this as one would expect. I think this will work itself out in 0.11.
How can one loop over the entities and update them ?
Same workaround (force update by changing selection state) given in: #959 (comment)