React-Hot-Loader 不保存状态。 v.4.12.21

React-Hot-Loader Not Preserving State. v.4.12.21

我按照给定的步骤 https://www.npmjs.com/package/react-hot-loader

安装 npm 安装 react-hot-loader

添加 react-hot-loader/babel 到你的 .babelrc:

//.babelrc { “插件”:[“react-hot-loader/babel”] }

将您的根组件标记为热导出:

//Button.js

class Button extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 1,
    };
  }

  handleClick = () =>
    this.setState({
      counter: this.state.counter + 1,
    });

  render() {
    return (
      <div>
        <h2> Cool Counter {this.state.counter} !!!!</h2>
        <button onClick={this.handleClick}>{this.state.counter}</button>
      </div>
    );
  }
}

export default hot(Button);

//App.js

import React from 'react';
import { hot } from 'react-hot-loader/root';
import Button from './controls/Button';

const App = () => (
  <div style={{ color: 'purple' }}>
    <Button />
  </div>
);
export default hot(App);

确保在 react 和 react-dom:

之前需要 react-hot-loader

//Main.js

import 'react-hot-loader';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import './main.scss';

ReactDOM.render(<App />, document.getElementById('container'));

如果需要hooks支持,使用@hot-loader/react-dom

npm install @hot-loader/react-dom

使用 webpack 别名

// webpack.config.js
module.exports = {
  // ...
  resolve: {
    alias: {
      'react-dom': '@hot-loader/react-dom',
    },
  },
};

//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-Hot-Loader-Test</title>
  </head>

  <body>
    <div id="container"></div>
    <script src="/public/main.js"></script>
    <link href="/public/main.css" rel="stylesheet" />
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
  </body>

//server.js

var webpack = require('webpack');
var WebPackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');

new WebPackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  hot: true,
  historyApiFallback: true,
}).listen(8080, 'localhost', function (err, result) {
  if (err) {
    return console.log(err);
  }

  console.log('Listening on localhost:8080');
});

//webpack.config.js

const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const devMode = process.env.NODE_ENV !== 'production';

module.exports = {
  mode: 'development',
  devtool: 'inline-source-map',
  entry: {
     main: ['react-hot-loader/patch', './src/main.js'],
  },
  resolve: {
    alias: {
      'react-dom': '@hot-loader/react-dom',
    },
    modules: [path.resolve('./src'), path.resolve('./node_modules')],
  },
  output: {
    path: path.resolve(__dirname, 'public'),
    filename: devMode ? '[name].js' : '[name].[chunkhash].js',
    publicPath: '/public/',
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,            
        use: ['react-hot-loader/webpack', 'babel-loader'],
        
      },
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
          },
          'css-loader',
          'sass-loader',
        ],
      },
    ],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: devMode ? '[name].css' : 's[name].[hash].css',
      chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
    }),
  ],  
  
};

//.babelrc

{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": ["@babel/plugin-proposal-class-properties", "react-hot-loader/babel"]
}

最后运行 2 命令

1. webpack -d
2. node server.js

结果: λ 节点服务器启动 运行

i 「wds」: Project is running at http://localhost:8080/
i 「wds」: webpack output is served from /public/
i 「wds」: Content not from webpack is served from G:\Projects\React-Second
i 「wds」: 404s will fallback to /index.html

react 热加载仅适用于 html,css,jsx 更改

问题: 钩子在点击按钮时不存储以前的状态,然后更改任何 css、html 或 jsx、UseState 或 Set 状态不保留状态,它始终以 1.

开头

请帮助我遗漏了什么,我已经挣扎了几个小时。

问候

沙兹

找到解决方案

//webpack.config.js

const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const devMode = process.env.NODE_ENV !== 'production';

module.exports = {
  mode: 'development',
  devtool: 'inline-source-map',
  entry: {
    main: ['webpack-dev-server/client?http://localhost:8080', 'webpack/hot/only-dev-server', './src/main.js'],
    // main: ['react-hot-loader/patch', './src/main.js'],
  },
  resolve: {
    alias: {
      'react-dom': '@hot-loader/react-dom',
    },
    modules: [path.resolve('./src'), path.resolve('./node_modules')],
  },
  output: {
    path: path.resolve(__dirname, 'public'),
    filename: devMode ? '[name].js' : '[name].[chunkhash].js',
    publicPath: '/public/',
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        // use: {
        //   loader: 'babel-loader',
        //   // options: {
        //   //   presets: ['@babel/preset-env', '@babel/preset-react'],
        //   // },
        // },
        use: ['react-hot-loader/webpack', 'babel-loader'],
        //use: ['babel-loader'],
      },
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
          },
          'css-loader',
          'sass-loader',
        ],
      },
    ],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin(),
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: devMode ? '[name].css' : 's[name].[hash].css',
      chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
    }),
  ],

  // devServer: {
  //   contentBase: path.join(__dirname),
  //   compress: false,
  //   port: 8080,
  //   historyApiFallback: true,
  //   watchContentBase: false,
  //   publicPath: '/public/',
  // },
};