【问题标题】:Using popup blocker enabled, getting a React error Too many re-renders使用弹出窗口拦截器,得到一个 React 错误 Too many re-renders
【发布时间】:2021-02-06 21:18:42
【问题描述】:

我有一个奇怪的问题..我正在打开一个从 graphql 查询返回的 blob,它是一个 pdf..如果我启用浏览器弹出窗口阻止程序,它会按预期工作,我会在 url 栏中收到一条消息,说一个弹出窗口被阻止..如果我将其设置为允许弹出窗口,我会在控制台中收到 50 多个 pdf 选项卡和一条错误消息,提示“重新渲染太多”。

如果我从

中删除“&& closeModal()”
{fileType.includes('pdf') && !isIE && window.open(documentSource) && closeModal()}

我只打开了一个 pdf,但调用页面变为空白并在控制台中显示不同的错误消息:

未捕获的错误:对象作为 React 子对象无效(发现:[object 窗户])。如果您打算渲染一组孩子,请使用 代替数组。

有人对我在打击代码中做错了什么有建议吗?

    const closeModal = () => {
    setLoadingMsg(true);
    setShowModal(false);
  };

  return (
    <Box>
      <Modal
        showModal={showModal}
        onEsc={closeModal}
        onClickOutside={closeModal}
      >
        <StyledModal>
          {documentData && (
            <StyledHeader>
              <StyledHeaderText>
                <Text size="14pt">
                  {documentData.file_name?.replace(/(-?[0-9]+([0-9]+ )?)/g, '')}
                </Text>
              </StyledHeaderText>
            </StyledHeader>
          )}

          {!documentError && (
            <StyledBox>
              {!isIE && (
                <img alt="Loading" src={Loading} width="auto" height="100px" />
              )}
              <Box>{showLoadingMsg ? 'Preparing your document...' : ''}</Box>
            </StyledBox>
          )}

          {fileType.includes('htm') && <Box />}

          {fileType.includes('pdf') && !isIE && window.open(documentSource, "_blank") && closeModal()}

          {fileType.includes('pdf') && isIE && (
            <Box>
              <a href={documentSource}>Download Ready</a>
              <StyledText>
                Please right-click the above link and select <strong>Save target as</strong> to
                download your document.
              </StyledText>
            </Box>
          )}

          {(fileType === 'error' || documentError) && (
            <StyledBox>
              <Text>There was an error fetching the requested document.</Text>
              <Text>Close the modal and try downloading again.</Text>
            </StyledBox>
          )}
          {(fileType === 'error' || documentError || isIE) && (
            <StyledFooter>
              <StyledCloseButton label="CLOSE" onClick={closeModal} />
            </StyledFooter>
          )}
        </StyledModal>
      </Modal>
      <DocumentsPage
        onDocumentClick={onDocumentClick}
        isLoading={loading}
        information={items}
        error={error}
        accountNumber={accountNumber}
      />
    </Box>

【问题讨论】:

    标签: reactjs react-router graphql window.open


    【解决方案1】:

    首先,您可以尝试在渲染之外管理所有 pdf 逻辑,例如:

    在你的回报:

    {checkTileType(fileType)};
    

    添加新功能:

    function checkTileType(type) {
      if (type.includes('htm')) {
        return <Box /> 
      }
    
      if (type.includes('pdf')) {
        if (isIE) {
          return <Box> ... </Box>;
        }
         
        closeModal();
        window.open(documentSource, "_blank");
        return;
      }
    }
    

    【讨论】:

    • 我将大部分逻辑移出并移到一个函数中。. 仍然收到太多重新渲染消息
    • 如果你能创建一个codepen就好了!
    • 我创建了一个沙箱,如果您将弹出窗口阻止程序设置为允许,它将打开一大堆标签页。请注意..codesandbox.io/s/stupefied-snyder-h6t73?file=/src/App.tsx
    • 很好,为了避免“重新渲染过多”消息,您可以将 setDocumentSourcesetFileType 移动到 useEffect 挂钩,例如:useEffect(() =&gt; { setDocumentSource("https://www.myairplane.com/Canon_w8400-sm-pc.pdf"); setFileType(documentSource); }, [documentSource]);。还将documentInfodocumentError 移出App 组件(性能)
    猜你喜欢
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    • 2016-10-27
    相关资源
    最近更新 更多