简体   繁体   English

如何呈现具有不同子级的反应门户模式?

[英]How do I render a react portal modal with different children?

Right now, I have a react portal rendering a 'pinnable' side drawer modal that will display based on a redux state.现在,我有一个反应门户呈现一个“可固定”的侧抽屉模式,它将根据 redux 状态显示。 The contents of the modal will have information based on where that modal was pinned from, in this case my notifications.模态的内容将包含基于模态固定位置的信息,在本例中为我的通知。

The problem I'm running into at the moment is that since the modal will be pinnable in multiple places, I'm not exactly sure of the logic on how to handle the modal contents if the modal is already pinned.我目前遇到的问题是,由于模态将在多个位置固定,如果模态已经固定,我不确定如何处理模态内容的逻辑。

I've tried/considered the following:我已经尝试/考虑了以下内容:

  1. Just have one portal render its children dynamically.只需让一个门户动态呈现其子门户即可。 Unfortunately the location of where the portal will be rendered does not contain the contents and logic of the modal, so I believe this can't be done.不幸的是,门户网站的渲染位置不包含模态的内容和逻辑,所以我认为这是不可能的。
  2. Compare props.children and if they're not identical, render the newer portal and deconstruct the other.比较props.children ,如果它们不相同,则渲染较新的门户并解构另一个。 I'm hesitant to use this approach since I believe there's a better solution out there.我对使用这种方法犹豫不决,因为我相信那里有更好的解决方案。
  3. Render the portals based on Ids and deconstruct/reconstruct where needed if one exists.根据 ID 呈现门户,并在需要时解构/重建门户(如果存在)。 I'm leaning towards this approach, but again I'd like to see if there's a better one.我倾向于这种方法,但我还是想看看是否有更好的方法。

Portal location:传送门位置:

export default function PaperContainer() {


return <div id="pinned-container"></div>;

}

Portal:门户网站:

export default function PinnedContainer(props) {
const pinned = useSelector(state => state.ui.isDrawerPinned);

return (
    pinned &&
    createPortal(            
            <div>
                <div>{props.children}</div>
            </div>
        ,
        document.getElementById('pinned-container')
    )
);
}

Where the portals are called (simplified for brevity):调用门户的位置(为简洁起见进行了简化):

export default function PortalCallLocationOne() {
    const dispatch = useDispatch();
    const pinContainer = () => {
         dispatch(toggleDrawer());
    };

 return  (
    <>
         <Button startIcon={<Icon>push_pin</Icon>} onClick={() => pinContainer}>
                 Pin Notification
         </Button>
         <PinnedContainer>
               //Notification
         </PinnedContainer>
    </>
   );
}

export default function PortalCallLocationTwo() {
     const dispatch = useDispatch();
     const pinContainer = () => {
         dispatch(toggleDrawer());
     };
     return (
<>
        <Button startIcon={<Icon>push_pin</Icon>} onClick={() => pinContainer}>
                 Pin List
        </Button>
       <PinnedContainer>
          // List
       </PinnedContainer>
     );
</>
   }

I tried going off of #3 and destroying pinned-container 's first child if it existed and replace it with the new children.我尝试离开#3 并销毁pinned-container的第一个孩子(如果它存在)并用新的孩子替换它。 This didn't work since React was expecting that child and kept throwing failed to execute removeChild on node errors.这是行不通的,因为 React 期待那个孩子并不断抛出failed to execute removeChild on node错误。

Unfortunately it looks like react is unable to replace portal children instead of appending them .不幸的是,React 似乎无法替换 portal children 而不是附加它们

However, I was able to solve my issue by unpinning the portal and repinning it with redux actions.但是,我能够通过取消固定门户并使用 redux 操作重新固定它来解决我的问题。

export default function PinnedContainer(props) {
const pinned = useSelector(state => state.ui.isDrawerPinned);

useEffect(() => {
    if (pinned) {
         dispatch(clearPinned());
         dispatch(pinDrawer(true));
      }
    }, []);

return (
    pinned &&
    createPortal(            
            <div>
                <div>{props.children}</div>
            </div>
        ,
        document.getElementById('pinned-container')
    )
);
}

Reducer:减速器:

export const initialState = {
    isDrawerPinned: false,
}

export const reducer = (state = initialState, action) => {
     switch(action.type){
       case actionTypes.PIN_DRAWER:
            return {
                ...state,
                isDrawerPinned: action.isPinned ? action.isPinned : !state.isDrawerPinned,
            };
    case actionTypes.CLEAR_PINNED:
            return {
                ...state,
                isDrawerPinned: state.isDrawerPinned ? !state.isDrawerPinned : state.isDrawerPinned
            };

}

}

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

相关问题 如何在React组件中将字符串呈现为子项? - How do I render a string as children in a React component? 如何强制模态的新渲染? - How do I force the fresh render of a modal? 在React组件中使用不同的子元素重用模式 - Reusing a modal, in a React component, with different children 如何使用 React 测试库测试 React 门户内部的模式? - How can I test a modal inside of a React Portal using React Testing Library? React + Foundation-在点击时具有不同道具的渲染模态 - React + Foundation - Render Modal with different props on click 如何在 Angular 组件中动态访问或呈现子项? - How do I dynamically access or render Children in an Angular Component? 语义UI反应模式:Portal.render():必须返回有效的React元素(或null) - Semantic UI React Modal : Portal.render(): A valid React element (or null) must be returned 如何关闭React Native Modal? - How do I close a React Native Modal? 如何在 React Modal 上显示组件 - How do I display a component on React Modal 如何在 Modal 组件中为我的文本呈现动态变量? - How do i render a dynamic variable for my text in the Modal component?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM