繁体   English   中英

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

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

现在,我有一个反应门户呈现一个“可固定”的侧抽屉模式,它将根据 redux 状态显示。 模态的内容将包含基于模态固定位置的信息,在本例中为我的通知。

我目前遇到的问题是,由于模态将在多个位置固定,如果模态已经固定,我不确定如何处理模态内容的逻辑。

我已经尝试/考虑了以下内容:

  1. 只需让一个门户动态呈现其子门户即可。 不幸的是,门户网站的渲染位置不包含模态的内容和逻辑,所以我认为这是不可能的。
  2. 比较props.children ,如果它们不相同,则渲染较新的门户并解构另一个。 我对使用这种方法犹豫不决,因为我相信那里有更好的解决方案。
  3. 根据 ID 呈现门户,并在需要时解构/重建门户(如果存在)。 我倾向于这种方法,但我还是想看看是否有更好的方法。

传送门位置:

export default function PaperContainer() {


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

}

门户网站:

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')
    )
);
}

调用门户的位置(为简洁起见进行了简化):

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>
     );
</>
   }

我尝试离开#3 并销毁pinned-container的第一个孩子(如果它存在)并用新的孩子替换它。 这是行不通的,因为 React 期待那个孩子并不断抛出failed to execute removeChild on node错误。

不幸的是,React 似乎无法替换 portal children 而不是附加它们

但是,我能够通过取消固定门户并使用 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')
    )
);
}

减速器:

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.

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