likes
comments
collection
share

React: 如何在全局挂载一个dom结构 (例如全局二维码的实现)?

作者站长头像
站长
· 阅读数 23

answer

在React中,全局挂载一个DOM结构(如全局二维码)可以通过以下几种方法实现:

  1. 使用React Portal: React Portal可以将子组件渲染到DOM树中的任何位置,而不仅仅是其父组件的DOM层次结构。通过这种方式,可以将全局二维码组件挂载到全局的DOM节点中。

  2. 使用Context和全局State管理: 使用React Context和全局状态管理(如Redux、MobX等)可以将全局状态传递给应用中的任意组件,然后在需要显示全局二维码的地方进行渲染。

  3. 直接操作DOM: 可以直接使用React的useEffect钩子和纯JavaScript的DOM操作来挂载和卸载全局的DOM节点。

方法一:使用React Portal

  1. public/index.html文件中添加一个全局容器:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React App</title>
</head>
<body>
  <div id="root"></div>
  <div id="global-qr-code-container"></div>
</body>
</html>
  1. 创建全局二维码组件:
// GlobalQRCode.js
import React from 'react';
import ReactDOM from 'react-dom';

const GlobalQRCode = ({ content }) => {
  return ReactDOM.createPortal(
    <div style={{ position: 'fixed', bottom: 20, right: 20, zIndex: 1000 }}>
      <img src={`https://api.qrserver.com/v1/create-qr-code/?data=${content}&size=100x100`} alt="QR Code" />
    </div>,
    document.getElementById('global-qr-code-container')
  );
};

export default GlobalQRCode;
  1. 在应用中使用全局二维码组件:
// App.js
import React, { useState } from 'react';
import GlobalQRCode from './GlobalQRCode';

const App = () => {
  const [showQRCode, setShowQRCode] = useState(false);
  const [qrContent, setQrContent] = useState('Hello World');

  return (
    <div>
      <button onClick={() => setShowQRCode(!showQRCode)}>
        {showQRCode ? 'Hide QR Code' : 'Show QR Code'}
      </button>
      {showQRCode && <GlobalQRCode content={qrContent} />}
    </div>
  );
};

export default App;

方法二:使用Context和全局State管理

  1. 创建一个全局Context:
// QRCodeContext.js
import React, { createContext, useState, useContext } from 'react';

const QRCodeContext = createContext();

export const QRCodeProvider = ({ children }) => {
  const [qrContent, setQrContent] = useState(null);

  return (
    <QRCodeContext.Provider value={{ qrContent, setQrContent }}>
      {children}
    </QRCodeContext.Provider>
  );
};

export const useQRCode = () => useContext(QRCodeContext);
  1. 创建全局二维码组件:
// GlobalQRCode.js
import React from 'react';
import { useQRCode } from './QRCodeContext';

const GlobalQRCode = () => {
  const { qrContent } = useQRCode();

  if (!qrContent) return null;

  return (
    <div style={{ position: 'fixed', bottom: 20, right: 20, zIndex: 1000 }}>
      <img src={`https://api.qrserver.com/v1/create-qr-code/?data=${qrContent}&size=100x100`} alt="QR Code" />
    </div>
  );
};

export default GlobalQRCode;
  1. 在应用中使用全局Context和二维码组件:
// App.js
import React from 'react';
import { QRCodeProvider, useQRCode } from './QRCodeContext';
import GlobalQRCode from './GlobalQRCode';

const App = () => {
  const { setQrContent } = useQRCode();

  return (
    <QRCodeProvider>
      <div>
        <button onClick={() => setQrContent('Hello World')}>Show QR Code</button>
        <GlobalQRCode />
      </div>
    </QRCodeProvider>
  );
};

export default App;

方法三:直接操作DOM

  1. public/index.html文件中添加一个全局容器:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React App</title>
</head>
<body>
  <div id="root"></div>
  <div id="global-qr-code-container"></div>
</body>
</html>
  1. 使用React的useEffect和DOM操作:
// GlobalQRCode.js
import React, { useEffect } from 'react';

const GlobalQRCode = ({ content }) => {
  useEffect(() => {
    const qrContainer = document.getElementById('global-qr-code-container');
    const qrCode = document.createElement('div');
    qrCode.style.position = 'fixed';
    qrCode.style.bottom = '20px';
    qrCode.style.right = '20px';
    qrCode.style.zIndex = '1000';
    qrCode.innerHTML = `<img src="https://api.qrserver.com/v1/create-qr-code/?data=${content}&size=100x100" alt="QR Code" />`;
    qrContainer.appendChild(qrCode);

    return () => {
      qrContainer.removeChild(qrCode);
    };
  }, [content]);

  return null;
};

export default GlobalQRCode;
  1. 在应用中使用全局二维码组件:
// App.js
import React, { useState } from 'react';
import GlobalQRCode from './GlobalQRCode';

const App = () => {
  const [showQRCode, setShowQRCode] = useState(false);
  const [qrContent, setQrContent] = useState('Hello World');

  return (
    <div>
      <button onClick={() => setShowQRCode(!showQRCode)}>
        {showQRCode ? 'Hide QR Code' : 'Show QR Code'}
      </button>
      {showQRCode && <GlobalQRCode content={qrContent} />}
    </div>
  );
};

export default App;

以上三种方法都可以实现全局挂载一个DOM结构。选择哪种方法取决于具体的需求和项目的复杂度。对于全局组件,React Portal和Context结合全局状态管理是更为常用和推荐的方式。

转载自:https://juejin.cn/post/7379151898568196136
评论
请登录