简体   繁体   English

从功能组件内部渲染功能组件

[英]Rendering functional component from inside a functional component

So I have a functional component which is a toolbar.所以我有一个功能组件,它是一个工具栏。 Its parent is a Text editor.它的父级是一个文本编辑器。 The toolbar has many child components which are buttons.工具栏有许多子组件,它们是按钮。 On clicking one of these buttons, I want a modal to appear.单击其中一个按钮时,我希望出现一个模式。 The logic of useModal . useModal的逻辑。 But the FormatToolbarModal does not appear.但是FormatToolbarModal没有出现。

I have read that all the rendering of a component must be done by the top level custom component?我读过一个组件的所有渲染都必须由顶级自定义组件完成? But I am unsure where to go from there.但我不确定 go 从那里到哪里。 I want this modal to be reusable as other options from the toolbar will use it.我希望此模式可重复使用,因为工具栏中的其他选项将使用它。

index.jsx索引.jsx

ReactDOM.render(routes, document.getElementById("app"));

App.jsx应用程序.jsx

const App = () => {
  return (
    <TextEditor/>
  )
}

TextEditor.jsx文本编辑器.jsx

const TextEditor = () => {
  return(
    <FormatToolbar>
      <FormatToolbarBlock format="link" icon={link2} />
      <FormatToolbarBlock format="image" icon={image} />
    </FormatToolbar>
    ... Editor stuff
  )
}


const FormatToolbarBlock = ({ format, icon }) => {
  const editor = useSlate();
  const {isShowing, toggle} = useModal();

  return (
    <FormatButton
      onMouseDown={e => {
        if(format === 'link'){
          toggle(e);
          <FormatToolbarModal       <---- here is my issue
            isShowing={isShowing}  
            hide={toggle}
          />
          } else if {
          ...
          }
      }}
    />
  )
}

UseModal.jsx使用Modal.jsx

const useModal = () => {
  const [isShowing, setIsShowing] = useState(false);

  function toggle() {
    setIsShowing(!isShowing);
  }

  return {
    isShowing,
    toggle,
  }
};

export default useModal;

FormatToolbarModal.jsx格式工具栏Modal.jsx

const FormatToolbarModal = ({ isShowing, hide }) => isShowing ? ReactDOM.createPortal(
  <React.Fragment>
    <p>I am a modal</p>
  </React.Fragment>, document.body 
): null;

export default FormatToolbarModal;

Hopefully from this, you can see my issue clearer.希望从此,您可以更清楚地看到我的问题。 Im new to React and hooks, so any advice is appreciated.我是 React 和 hooks 的新手,所以任何建议都值得赞赏。

Thanks!谢谢!

You're calling the function, but not passing the resulting JSX elements to anything that will render them.您正在调用 function,但没有将生成的 JSX 元素传递给将呈现它们的任何东西。 Think of the bootstrapping operation you use with the top-level component, where you pass the result into ReactDOM.render or similar.想想你在顶级组件中使用的引导操作,你将结果传递给ReactDOM.render或类似的。 That's what puts it on the page.这就是把它放在页面上的原因。 You need to do the same thing with the result of calling your modal function.您需要对调用模态 function 的结果执行相同的操作。

You have a couple of options:你有几个选择:

  1. You might do it by having a flag that your function sets, and then conditionally rendering the modal within another component.您可以通过设置一个 function 设置的标志,然后在另一个组件中有条件地呈现模式来做到这一点。

  2. You might render it as (in?) a portal .您可以将其渲染为(在?)一个门户

React 101.反应 101。

  1. React naming convention: Component names should follow pascal-case. React 命名约定:组件名称应遵循 pascal-case。

    eg: from your code showModal should be ShowModal.例如:从你的代码 showModal 应该是 ShowModal。

also your code is not sufficient to understand the structure(how and where these components are being rendered).您的代码也不足以理解结构(这些组件的呈现方式和位置)。 what i'm saying is there are many other possible ways this could go south, but this alone could make this bug.我要说的是还有很多其他可能的方法可以使 go 南下,但仅此一项就可能导致此错误。

Okay so as I suspect and as TJ Crowder mentioned.好吧,正如我怀疑和 TJ Crowder 提到的那样。 My FormatButton did not know how to render such a component.我的FormatButton不知道如何呈现这样的组件。 I moved the component like so, and wrapped it in a fragment.我像这样移动了组件,并将其包装在一个片段中。 Now everything works.现在一切正常。

For anyone having the same issue.对于任何有同样问题的人。 Check out react portals.查看反应门户。 Also, this link helped: https://levelup.gitconnected.com/create-a-modal-with-react-hooks-357c8aae7c3f此外,此链接有帮助: https://levelup.gitconnected.com/create-a-modal-with-react-hooks-357c8aae7c3f

TextEditor.jsx文本编辑器.jsx

const FormatToolbarBlock = ({ format, icon }) => {
  const editor = useSlate();
  const {isShowing, toggle} = useModal();

  return (
    <>
    <FormatButton
      onMouseDown={e => {
        if(format === 'link'){
          toggle(e);
          } else if {
          ...
          }
      }}
    />
    <FormatToolbarModal
      isShowing={isShowing}  
      hide={toggle}
    />
    </>
  )
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM