如何将Slate JS悬停菜单转换为React Hooks?

时间:2019-10-06 17:57:23

标签: react-hooks slatejs

Slate JS提供了一个漂亮的hover menu based on a traditional Class component示例。我的目标是将其转换为与React Hooks一起使用。我想我已经95%了,但是我对如何将某些props从Editor组件传递到updateMenu()函数(由生命周期函数调用)感到困惑。这是Class和Hook组件的伪代码表示形式:

班级

class EditorWithHoveringMenu extends Component {
  menuRef = React.createRef()
  componentDidMount = () => {
    this.updateMenu();
  };
  componentDidUpdate = () => {
    this.updateMenu();
  };
  updateMenu = () => {
    const menu = this.menuRef.current;
    if (!menu) return;

    const { value: {fragment, selection } } = this.props; // the future problem
    ...do more stuff
  }
  renderEditor = (props, editor, next) => {
    const children = next();
    return (
      <React.Fragment>
        {children}
        <HoverMenu ref={this.menuRef} editor={editor} />
      </React.Fragment>
    );
  };
  render() {
    return (
      <Editor
        value={this.props.value}
        renderEditor={this.renderEditor}
      />
  }
}

挂钩

function Editor() {
  const menu = useRef(null);
  const { text, setText } = useContext(EditorContext); // editor state now derived from context

  // In practical terms, this effect should run whenever text is selected/highlighted or deselected.
  useEffect(() => {
    updateMenu(menu, ???);
  });

  const updateMenu = (menuRef, value) => {
    const menu = menuRef.current;
    if (!menu) return;
    const { fragment, selection } = value; // Not sure how to get at these without `this`
    ...do more stuff
  }
  const renderEditor = (props, editor, next) => {
    const children = next();
    return (
      <React.Fragment>
        {children}
        <HoverMenu ref={menu} editor={editor} />
      </React.Fragment>
    );
  };

  return (
    <Editor
      value={Value.fromJSON(text)}
      renderEditor={renderEditor}
    />
  )
}

基本上,我已经将updateMenu()重新定义为不引用this,但是尽管我可以轻松地传递菜单引用,但是我不理解如何访问编辑器的选定/突出显示的文本,这显然是以前是通过道具传递的。

1 个答案:

答案 0 :(得分:0)

通过一些反复试验,我能够解决此问题。检查原始的Class组件示例,解构const { value: {fragment, selection } } = this.props;引用了slate.js Value object

一旦我了解到,这就像将text的值化副本(来自useContext引用)作为参数传递给updateMenu()一样简单:

const { text, setText } = useContext(EditorContext);

// From this
useEffect(() => {
  updateMenu(menu, ???);
});

// To this
useEffect(() => {
  updateMenu(menu, Value.fromJSON(text));
});