Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't update editor value with api #1269

Closed
sanj44 opened this issue Dec 3, 2021 · 6 comments
Closed

Can't update editor value with api #1269

sanj44 opened this issue Dec 3, 2021 · 6 comments
Labels

Comments

@sanj44
Copy link

sanj44 commented Dec 3, 2021

when updating value of Editor with api returned data or load from local storage it doesn't update or retender to show that data in editor, was working fine with slate-react@0.65.2 but updating version greater > 0.70.0 with plate 8 introduced this issue.

@sanj44 sanj44 added the bug Something isn't working label Dec 3, 2021
@zbeyens zbeyens changed the title when updating value of Editor with api returned data or load from local storage it doesn't update or rerender to show that data in editor, was working fine with slate-react@0.65.2 but updating version greater > 0.70.0 introduced this issue on Plate 8.0. Can't update editor value with api Dec 3, 2021
@zbeyens zbeyens added the core label Dec 3, 2021
@zbeyens
Copy link
Member

zbeyens commented Dec 6, 2021

Thanks for the issue. Can you provide a sandbox?

@deyayan
Copy link

deyayan commented Dec 13, 2021

@zbeyens I am experiencing the same problem. Just curious, is it because of this change: ianstormtaylor/slate#4540

If so what can we do to achieve the requirement?

@zbeyens zbeyens added the slate label Dec 13, 2021
@mallison
Copy link

I've created a minimal reproduction https://codesandbox.io/s/affectionate-worker-i5nyb?file=/src/App.js

Clicking the button updates the value state but the update is not reflected in Plate.

@zbeyens
Copy link
Member

zbeyens commented Jan 20, 2022

From @dylans on Slack:

Yes, treating Slate as a controlled component didn't actually work as expected, so it was made more explicit that it's an uncontrolled components. There's a documentation update for Slate and a pile of issues people opened that I commented on. See ianstormtaylor/slate#4540 and friends

@afrou04
Copy link

afrou04 commented Mar 3, 2022

https://docs.slatejs.org/walkthroughs/06-saving-to-a-database

I had the same problem. I solved it by using resetNodes.

  /**
  * resetNodes resets the value of the editor.
  * It should be noted that passing the `at` parameter may cause a "Cannot resolve a DOM point from Slate point" error.
  */
  resetNodes<T extends Node>(
    editor: Editor,
    options: {
      nodes?: Node | Node[],
      at?: Location
    } = {}
  ): void {
    const children = [...editor.children]

    children.forEach((node) => editor.apply({ type: 'remove_node', path: [0], node }))

    if (options.nodes) {
      const nodes = Node.isNode(options.nodes) ? [options.nodes] : options.nodes

      nodes.forEach((node, i) => editor.apply({ type: 'insert_node', path: [i], node: node }))
    }

    const point = options.at && Point.isPoint(options.at)
      ? options.at
      : Editor.end(editor, [])

    if (point) {
      Transforms.select(editor, point)
    }
  }

If you want to completely initialize the editor, you can do the following.

import { getPlateActions } from '@udecode/plate'

const { resetEditor, value } = getPlateActions(editorId)

value(initialValue)
resetEditor()

@linonetwo
Copy link

And maybe rename it to make it clear:

const { resetEditor, value: updateEditorValue } = getPlateActions(editorID);

Also, attache my example of loading new value if store changed by other client:

  const editorID = props.currentTiddler;
  const { resetEditor, value: updateEditorValue } = getPlateActions(editorID);
  // Add the initial value when setting up our state.
  const [currentAst, setCurrentAst] = useState<Array<TNode<AnyObject>>>(deserialize(props.tiddlerText));
  /** current text is only used for compare, we don't want it trigger rerender, so use ref to store it */
  const currentTextRef = useRef<string>(props.tiddlerText);
  // update current value from props
  useEffect(() => {
    // there will be cases that triple return replaced with double return (trim),  cause here rerender, but I think it is ok, not so frequent
    if (currentTextRef.current !== props.tiddlerText) {
      const newValue = deserialize(props.tiddlerText);
      setCurrentAst(newValue);
      updateEditorValue(newValue);
      resetEditor();
    }
  }, [props.tiddlerText, currentTextRef, updateEditorValue, resetEditor]);
  const onChange = useDebouncedCallback(
    (newValue: Array<TNode<AnyObject>>) => {
      setCurrentAst(newValue);
      const newText = serialize(newValue);
      props.saver.onSave(newText);
      currentTextRef.current = newText;
    },
    [props.saver.onSave],
    props.saver.interval,
  );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants