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

Cannot access current state from execute callback #251

Open
zenodallavalle opened this issue Sep 10, 2021 · 4 comments
Open

Cannot access current state from execute callback #251

zenodallavalle opened this issue Sep 10, 2021 · 4 comments

Comments

@zenodallavalle
Copy link

I'm trying to create a custom ICommand that needs to access a state property.

When execute is called the state he's reading is not updated, is what it were when MDEditor component was rendered.

check this example on code sandbox example.

@pnovales
Copy link

pnovales commented Dec 3, 2021

Could be good improvement to have access to the current state from execute callback

@jaywcjlove
Copy link
Member

jaywcjlove commented Dec 4, 2021

@zenodallavalle

https://codesandbox.io/embed/uiwjs-react-md-editor-issues-251-lo6yp?fontsize=14&hidenavigation=1&theme=dark

import MDEditor from "@uiw/react-md-editor";
import { useState, useEffect, useRef } from "react";

export default function App() {
  const initialValue = "";
  const [val, setVal] = useState(initialValue);
  const history = useRef([val]);

  useEffect(() => {
    console.log("History was updated to", history.current);
  }, [history]);

  const command = {
    name: "back",
    keyCommand: "back",
    buttonProps: { "aria-label": "back", disabled: history.current.length < 2 },
    icon: <span>Back</span>,
    execute: () => {
      setVal(history.current[history.current.length - 2]);
      history.current = history.current.filter(
        (h, i) => i < history.current.length - 1
      );
    }
  };

  const command2 = {
    name: "back anyway",
    keyCommand: "back anyway",
    buttonProps: { "aria-label": "back anyway" },
    icon: <span>Back anyway</span>,
    execute: () => {
      console.log("For me history is", history.current);
      setVal(history.current[history.current.length - 2]);
      history.current = history.current.filter(
        (h, i) => i < history.current.length - 1
      );
    }
  };

  return (
    <div className="App">
      <MDEditor
        commands={[command, command2]}
        value={val}
        onChange={(v) => {
          setVal(v);
          history.current = [...history.current, v];
          // setHistory((h) => [...h, v]);
        }}
      />
      <button
        disabled={history.current.length < 2}
        onClick={() => {
          setVal(history.current[history.current.length - 2]);
          history.current = history.current.filter(
            (h, i) => i < history.current.length - 1
          );
        }}
      >
        Undo
      </button>

      <div>
        <h6 style={{ margin: 2 }}>Showing current value for val</h6>
        <p style={{ backgroundColor: "yellow" }}>{val}</p>
      </div>
    </div>
  );
}

@zenodallavalle
Copy link
Author

@jaywcjlove this is a good workaround. It's not using useState hook though. I think it is the same issue as #297. Also, when history.current.length become greater or equal than 2, disabled should become false, but that's not rendered and button is still disabled.

@jaywcjlove
Copy link
Member

@zenodallavalle Yes, I haven't found a solution yet.

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

No branches or pull requests

3 participants