I think the problem come from the state inside the Equation component which is not initialized for each Equation. It is probably an expected behaviour but I don't know how to do it correctly.
I precise that I don't want to use Block like in the documentation example because I want my equation to be inline.
The only solution I tought about would be to move the Equation edition feature outside of the decorator.
I did a simplified version of the code that replicate the bug :
import { useState } from 'react'
import {
Editor,
EditorState,
CompositeDecorator,
Modifier,
} from 'draft-js'
import 'draft-js/dist/Draft.css'
function findEquationEntities(contentBlock, callback, contentState) {
contentBlock.findEntityRanges((character) => {
const entityKey = character.getEntity()
return (
entityKey !== null &&
contentState.getEntity(entityKey).getType() === 'EQUATION'
)
}, callback)
}
function Equation({ contentState, entityKey }) {
const { math: initialMath } = contentState.getEntity(entityKey).getData()
const [math, setMath] = useState(initialMath || '')
//This following state is not initialized for each Equation. For the equation containing "b" we have the following console.log result :
//console.log(initialMath) will be "b"
//console.log(math) will be "c"
return <b>{math}</b>
}
function getSelectedText(editorState) {
const selectionState = editorState.getSelection()
const anchorKey = selectionState.getAnchorKey()
const currentContent = editorState.getCurrentContent()
const currentContentBlock = currentContent.getBlockForKey(anchorKey)
const start = selectionState.getStartOffset()
const end = selectionState.getEndOffset()
const selectedText = currentContentBlock.getText().slice(start, end)
return selectedText
}
function addEntity(type, mutability, data, editorState, setEditorState) {
const selectionState = editorState.getSelection()
const contentState = editorState.getCurrentContent()
const contentStateWithEntity = contentState.createEntity(
type,
mutability,
data
)
const entityKey = contentStateWithEntity.getLastCreatedEntityKey()
const contentStateWithHelp = Modifier.applyEntity(
contentStateWithEntity,
selectionState,
entityKey
)
const newEditorState = EditorState.set(editorState, {
currentContent: contentStateWithHelp,
})
return setEditorState(newEditorState)
}
function App() {
const decorator = new CompositeDecorator([
{
strategy: findEquationEntities,
component: Equation,
},
])
const [editorState, setEditorState] = useState(() =>
EditorState.createEmpty(decorator)
)
function turnIntoEquation() {
const math = getSelectedText(editorState)
addEntity(
'EQUATION',
'IMMUTABLE',
{ math },
editorState,
setEditorState
)
}
return (
<>
<Editor editorState={editorState} onChange={setEditorState} />
<button onClick={turnIntoEquation}>Turn into equation</button>
</>
)
}
export default App
Fun behaviours :
It does not occur without text before the equation :
I am creating a TeX editor using a decorator. When I add an equation before another one, the new equation take the value from the second one :
https://user-images.githubusercontent.com/10225722/187986381-24fb3222-8e7c-4a0c-8b36-42a80ad83878.mp4
I think the problem come from the state inside the Equation component which is not initialized for each Equation. It is probably an expected behaviour but I don't know how to do it correctly.
I precise that I don't want to use Block like in the documentation example because I want my equation to be inline.
The only solution I tought about would be to move the Equation edition feature outside of the decorator.
I did a simplified version of the code that replicate the bug :
Fun behaviours : It does not occur without text before the equation :
https://user-images.githubusercontent.com/10225722/187989685-933279dc-dad0-485f-8068-7d486cd4b1ad.mp4
The behaviour disappears if I create a third equation before :
https://user-images.githubusercontent.com/10225722/187989812-ff422b9f-c3b0-4c29-ab60-341a98d67350.mp4