Skip to content
This repository has been archived by the owner on Feb 6, 2023. It is now read-only.

state in decorator are memorised #3163

Open
chadox1292 opened this issue Sep 1, 2022 · 0 comments
Open

state in decorator are memorised #3163

chadox1292 opened this issue Sep 1, 2022 · 0 comments

Comments

@chadox1292
Copy link

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 :

React.App.-.Google.Chrome.2022-09-01.20-25-34.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 :

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 :

React.App.-.Google.Chrome.2022-09-01.20-44-46.mp4

The behaviour disappears if I create a third equation before :

React.App.-.Google.Chrome.2022-09-01.20-44-29.mp4
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant