简体   繁体   中英

ReferenceError: window is not defined in typescript

I am making a barcode scanner to scan both code128 and pdf417 and I am using react-qr-barcode-scanner to do so in typescript. However I get this error when running the code:

Server Error
ReferenceError: window is not defined

This error happened while generating the page. Any console logs will be displayed in the terminal window.

Here is my code: (ScannerTest.tsx)

import { useState } from 'react';
import BarcodeScannerComponent from 'react-qr-barcode-scanner';


export const ScannerTest = () => {
    const [camera, setCamera] = useState(false);
    const [data, setData] = useState("Not Found");
    return (
        <div >
            <div>SCANNER!</div>
            <button onClick={() => setCamera(!camera)}>
                {camera ? "Stop" : "Start"}
            </button>
            <div className="container">
                {camera &&
                    <div>
                        <BarcodeScannerComponent
                            width={500}
                            height={500}
                            onUpdate={(err, result) => {
                                if (result) {
                                    setData(result?.text)
                                }
                            }}
                        />
                        <p>{data}</p>
                    </div>}
            </div>
        </div>
    );
}

export default ScannerTest;

How can I avoid this error?

That looks like a Next.js error. Your React app is being built on the server side in a NodeJS environment where the window object does not exist. The earliest you can access window is inside an effect hook or lifecycle method:

console.log(window) // undefined

React.useEffect(() => {
  console.log(window); // defined
}, []);

If the window object is being accessed beyond your control in some library component, then you need to prevent anything which includes it from being rendered until you know you are in a browser environment (ie the markup has been hydrated):

const useHydrated = () => {
  const [hydrated, setHydrated] = React.useState(false);
  
  React.useEffect(() => {
    setHydrated(true);
  }, []);

  return hydrated;
};

And in your component:

const hydrated = useHydrated();

return hydrated ? (
  <div>
    ...
  </div>
) : null;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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