В процессе переноса моего портфолио из компонентов класса в функциональные компоненты с перехватчиками я получаю некоторые ошибки в моей производственной сборке, которых раньше не было. Все мои компоненты являются функциональными компонентами (за исключением границы ошибки), которые используют либо useState, либо useEffect, но, похоже, наличие одного из них вызывает эту ошибку:
"Нарушение инварианта: ошибка Minified React # 298; Хуки могут вызываться только внутри тела компонента функции."
Один из компонентов, вызывающих ошибку:
import React, { useState, memo } from 'react';
import { NavLink } from 'react-router-dom';
import { NavBrand, Nav } from './styles';
import Hamburger from './Hamburger';
import { Links, Link } from './styles';
function NavBar() {
const [open, handleMenu] = useState(false);
return (
<Nav>
<NavBrand onClick={() => handleMenu(false)}>
<NavLink to="/">
<i className="icon-brand" />
</NavLink>
</NavBrand>
<Hamburger open={open} onClick={() => handleMenu(!open)} />
<Links open={open} role="menu">
<Link
onClick={() => handleMenu(false)}
to="/"
exact
>
Home <i className="icon-home" />
</Link>
<Link
onClick={() => handleMenu(false)}
to="/portfolio"
>
Portfolio <i className="icon-briefcase" />
</Link>
<Link
onClick={() => handleMenu(false)}
to="/contact"
>
Contact <i className="icon-message-square" />
</Link>
</Links>
</Nav>
);
};
export default memo(NavBar);
Webpack.config.js
module.exports = function(env, argv) {
const isProd = argv.mode === 'production';
const plugins = [
new webpack.DefinePlugin({
NODE_ENV: JSON.stringify(argv.mode),
GA_ID: JSON.stringify(process.env.GA_ID)
}),
new WebpackBar({ name: 'portfolio', color: '#269bda' })
];
if (isProd) {
plugins.push(
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html'
}),
new CopyWebpackPlugin(['netlify', 'pwa', 'static']),
new ManifestPlugin({
fileName: 'asset-manifest.json'
}),
new CompressionPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: /\.js$|\.css$/,
minRatio: 0.9,
deleteOriginalAssets: false
}),
new SWPrecacheWebpackPlugin({
// By default, a cache-busting query parameter is appended to requests
// used to populate the caches, to ensure the responses are fresh.
// If a URL is already hashed by Webpack, then there is no concern
// about it being stale, and the cache-busting can be skipped.
dontCacheBustUrlsMatching: /\.\w{8}\./,
filename: 'service-worker.js',
// staticFileGlobs: ['/vendor.bundle.js'],
logger(message) {
if (message.indexOf('Total precache size is') === 0) {
// This message occurs for every build and is a bit too noisy.
return;
}
console.log(message);
},
// minify and uglify the script
minify: true,
// For unknown URLs, fallback to the index page
navigateFallback: '/index.html',
// Don't precache sourcemaps, build asset manifest,
// netlify redirects, or app js.
staticFileGlobsIgnorePatterns: [
/\.map$/,
/manifest.json$/,
/_redirects$/,
/js.bundle.js$/,
/[0-9].bundle.js$/
]
}),
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
}),
new webpack.optimize.AggressiveMergingPlugin(),
new MiniCssExtractPlugin({
filename: 'styles.css',
chunkFilename: '[id].css'
})
);
} else {
plugins.push(
new webpack.HotModuleReplacementPlugin(),
new BrowserSyncPlugin(
// BrowserSync options
{
host: 'localhost',
port: 8080,
open: false,
// proxy the Webpack Dev Server endpoint
// (which should be serving on http://localhost:8080/)
// through BrowserSync
proxy: 'http://localhost:8080/',
logPrefix: 'Portfolio'
},
// prevent BrowserSync from reloading the page
// and let Webpack Dev Server take care of this
{
reload: true
}
),
new CaseSensitivePathsPlugin(),
new FriendlyErrorsWebpackPlugin(),
new SystemBellPlugin(),
new DuplicatePackageCheckerPlugin(),
new StyleLintPlugin({
files: './app/assets/scss/*.scss'
})
);
}
return {
devtool: isProd ? 'hidden-source-map' : 'cheap-module-source-map',
context: sourcePath,
entry: {
js: [
// react-error-overlay
!isProd && 'react-dev-utils/webpackHotDevClient',
// fetch polyfill
isProd && 'whatwg-fetch',
// app entry
'app.tsx'
].filter(Boolean)
},
output: {
path: publicPath,
filename: '[name].bundle.js',
devtoolModuleFilenameTemplate: isProd
? info => path.relative(sourcePath, info.absoluteResourcePath).replace(/\\/g, '/')
: info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')
},
module: {
rules: [
{
test: /\.html$/,
exclude: /node_modules/,
use: {
loader: 'html-loader'
}
},
{
test: /\.js$/,
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: false
}
},
{
test: /\.json$/,
loader: 'json-loader',
type: 'javascript/auto'
},
{
test: /\.(scss|css)$/,
use: [
isProd && {
loader: MiniCssExtractPlugin.loader
},
!isProd && {
loader: 'style-loader',
options: {
sourceMap: false
}
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
].filter(Boolean)
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader'
}
]
},
{
test: /\.(ts|tsx)?$/,
use: 'ts-loader',
exclude: /node_modules/
},
{ enforce: 'pre', test: /\.js$/, loader: 'source-map-loader' },
{
test: /\.(ttf|eot|svg|woff|woff2)(\?[a-z0-9]+)?$/,
loader: 'file-loader'
},
{
test: /\.(png|jpg)$/,
exclude: /node_modules/,
use: ['file-loader']
}
]
},
resolve: {
extensions: [
'.webpack-loader.js',
'.web-loader.js',
'.loader.js',
'.jsx',
'.tsx',
'.js',
'.ts'
],
modules: [path.resolve(__dirname, 'node_modules'), sourcePath]
},
plugins,
// split out vendor js into its own bundle
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'initial'
}
}
}
},
performance: isProd && {
maxAssetSize: 600000,
maxEntrypointSize: 600000,
hints: 'warning'
},
stats: {
colors: {
green: '\u001b[32m'
}
},
devServer: {
contentBase: './src',
historyApiFallback: true,
port: 8080,
compress: isProd,
inline: !isProd,
hot: false,
quiet: true,
before: function(app) {
// This lets us open files from the runtime error overlay.
app.use(errorOverlayMiddleware());
}
}
};
};
Ошибка не возникает в моей среде разработки, и я добавил плагинact-hooks eslint , который должен отлавливать любое из этих инвариантных нарушений.
Кто-нибудь еще сталкивался с проблемами, связанными с продуктом, с React 16.7.0-alpha, как это? Что я делаю не так?