Search code examples
reactjswebpackgoogle-chrome-extensionreact-hooks

React.js/Webpack/Chrome Extension Error: Cannot read properties of null (reading 'useEffect')


I am building a Chrome extension, using React, which need webpack to make it work.

I created the Popup.jsx and it worked well with "useState", no problem. But with the index.jsx (the one that injects the code in a page) neither useState or useEffect are working.

I get the error "Uncaught TypeError: Cannot read properties of null (reading 'useState')"

Here is a simplified version of the index.jsx

import React, { useState, useEffect } from 'react'
import { render } from 'react-dom'


function Insert() {

    const [sendResultLabel, setSendResultLabel] = useState("test")

    /*render(
        (
            <div>{sendResultLabel}
            </div >
        ), document.querySelector('section > div')
    )*/
}

Insert()  

And here my Webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
    entry: {
        popup: './src/popup.jsx',
        index: './src/index.jsx'
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js'
    },
    module: {
        rules: [{
            test: /\.(js|jsx)$/,
            exclude: '/node_modules/',
            use: {
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env', '@babel/preset-react']
                }
            }
        },
        {
            test: /\.css$/,
            use: ["style-loader", "css-loader"],
            exclude: '/node_modules/',
        },
        {
            test: /\.s[ac]ss$/i,
            use: [
                // Creates `style` nodes from JS strings
                "style-loader",
                // Translates CSS into CommonJS
                "css-loader",
                // Compiles Sass to CSS
                "sass-loader",
            ],
        }
        ]
    },
    plugins: [new HtmlWebpackPlugin({
        template: './src/popup.html',
        filename: 'popup.html',
    }),
    new CopyPlugin({
        patterns: [
            { from: "public" },
        ],
    }),
    ]

}; 

I believe it must be something to do with Webpack that I am missing. Do you have any idea?

Thanks!!


Solution

  • Well, I got an answer myself. It was nothing to do with webpack.

    Hooks only can be used inside component functions, so what I got to do was to create a new component file, (Wich I called "Insert.js"), with most of my logic (including the hooks), and in the Index.jsx, I only inserted this new component.

    That way it worked as I wanted.