0

Slate JS 提供了一个基于传统 Class 组件的漂亮的悬停菜单示例。我的目标是将其转换为与 React Hooks 一起使用。我想我已经完成了 95% 的工作,但是我对如何将某些道具从 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()为 not reference this,但是虽然我可以轻松地传递菜单 ref,但我不明白如何访问编辑器选择/突出显示的文本,这显然是以前通过 props 传递的。

4

1 回答 1

0

通过一些试验和错误,我能够解决这个问题。检查原始 Class 组件示例,解构const { value: {fragment, selection } } = this.props;是对slate.js 值对象的引用。

text一旦我理解了这一点,它就像将(来自参考)的值化副本useContext作为参数传递给updateMenu()

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

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

// To this
useEffect(() => {
  updateMenu(menu, Value.fromJSON(text));
});
于 2019-10-06T21:50:45.030 回答