如何仅更新一个组件?表

时间:2017-09-17 10:06:37

标签: reactjs webpack react-router webpack-hmr react-hot-loader

我使用此配置工作应用程序没有任何错误

的package.json:

 ...
    "react-hot-loader": "^3.0.0-beta.7",
    "webpack": "^3.6.0",
    "webpack-dev-server": "^2.8.2"
    "react-router-dom": "^4.2.2",
...

babel.rc

{
  "presets": [
    ["es2015", {"modules": false}],
    "stage-2",
    "react"
  ],
  "plugins": [
    "react-hot-loader/babel"
  ]
}

webpack.config.js:

const path = require('path');
const webpack = require('webpack');

module.exports = {
  devtool: 'eval',
  entry: [
    'babel-polyfill',
    'react-hot-loader/patch',
    'webpack-dev-server/client?http://192.168.1.33:3000',
    'webpack/hot/only-dev-server',
    './app/index.js'
  ],
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, '../dist'),
    publicPath: '/static/'
  },
  module: {
    rules: [
      {test: /\.(jsx|js)$/, loader: 'babel-loader', exclude: /node_modules/},
    ],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new webpack.NoEmitOnErrorsPlugin(),
  ],
  devServer: {
    host: '192.168.1.33',
    port: 3000,
    historyApiFallback: true,
    hot: true,
    compress: true,
  }
};

全部以yarn webpack-dev-server --host 192.168.1.33开头。我使用来自gaeron< hot-loader和 module.hot.accept AppContainer 来自webpack HMR的入口点 index.js:

import React from 'react';
import ReactDOM from 'react-dom'
import {AppContainer} from 'react-hot-loader'
import Nav from './navigation';

const rootEl = document.getElementById('root');
const render = Component => {
  ReactDOM.render(
    <AppContainer>
      <MuiThemeProvider>
        <Component/>
      </MuiThemeProvider>
    </AppContainer>,
    rootEl
  )
};

render(Nav);

if (module.hot) {
  module.hot.accept('./navigation', () => {
    const Nav = require('./navigation').default; //working same without this row
    render(Nav)
  })
}

来自下一个组件的所有routig - ./ navigation.index.js:

import React from 'react';
import Drawer from 'material-ui/Drawer';
import MenuItem from 'material-ui/MenuItem';
import IconButton from 'material-ui/IconButton';
import Main from '../menu/index';
import PredTable from '../tablo/predTable';
import Confs from '../configs/confs';
import {
  BrowserRouter as Router,
  Route,
  Link
} from 'react-router-dom'

let routes = [
  {
    exact: true,
    path: '/',
    main: () => <Main/>
  },
  {
    path: '/Conf',
    main: () => <Confs/>
  }
];


function requireAllDataNames(requireContext) {
  return requireContext.keys();
}

const FileNames = requireAllDataNames(
  require.context('../../../src/data', false, /.json$/)
);

const Auth = (props) => (
    <PredTable id={props['props']}/>
);

export default class Nav extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      props: []
    };
  }

  getLink(file) {
    let id = file.substring(2, file.length - 5);
    return <Link to={'/' + id} key={id}>{id}</Link>
  }

  getRoute(file) {
    let id = file.substring(2, file.length - 5);
    return <Route 
      path={'/' + id} 
      key={id} 
      component={(props) => <Auth props={id} {...props} />}
    />
  }

  render() {
    return (
      <Router>
        <div style={{display: 'flex'}} ref="nav">
          <Drawer
            docked={true}
            width={200}
          >
            <Link to='/' key="main">Меню</Link>
            <Link to='/Confs' key="conf">Settings</Link>
            {FileNames.map((v) => (
              this.getLink(v)
            ))}
          </Drawer>
          <div style={{flex: 1}}>
            {routes.map((route, index) => (
              <Route
                key={index}
                path={route.path}
                exact={route.exact}
                component={route.main}
              />
            ))}
            {FileNames.map((v) => (
              this.getRoute(v)
            ))}
          </div>
        </div>
      </Router>
    );
  }
}

predTable 中导入两个主要组件:

import React from 'react';
import Table from '../table/table';
import Clock from '../clock2';


export default class PredTable extends React.Component {

  constructor(props) {
    super(props);
    let Config = require('../../../src/configs/' + props.id + '.json');
    this.state = {
      id: props['id'],
      conf: Config
    }
  }


  render() {
    return (
      <div>
        <Table tableId={this.state.id}/>
        <Clock size={350} tableId={this.state.id} timeFormat="24hour" hourFormat="standard"/>
      </div>
    );
  }
}

../ tablo / table Table 组件中导入json文件,当此文件中发生更改时,我在控制台中收到了此消息:

[WDS] App updated. Recompiling...
[WDS] App hot update...
[HMR] Checking for updates on the server...
[HMR] Updated modules:
[HMR]  - ../src/data/2.json
[HMR]  - ../src/data recursive ^\.\/.*\.json$
[HMR]  - ./app/table/table.js
[HMR]  - ./app/table/predTable.js
[HMR]  - ./app/navigation/index.js
[HMR] App is up to date.

所以应用程序热重新加载似乎正在运行,但是它会重新加载路径中从父 Nav 到路径的所有组件到 PredTable 。但是使用predTable刷新还可以刷新组件 Clock ,即可导入其中。这是我想避免的事情。

所以问题是 - 如何更新仅一个组件 - ,而不是组件的整个路径 Navigation-PredTable-Table

在一些JS反应聊天中我得到了消息,这是HMR的正常行为。重新加载所有父组件。更改 data.json

对于结构示例:

-index.js  
--navigation.js (**reloaded**. Start or Routing, reloaded cause have predTable,js, that contain table.js with imported data.json)  
---predTable.js (**reloaded**. contain table.js with imported data.json)    
----table.js (**reloaded**. imported data.json. I wanna that only **THIS** component reloading)      
---->data.json (import)    
----clock.js  
---conf.js  
---multiTable.js (reloading cause call table.js inside, BUT! with different data3.json)  
---->table.js  
------data3.json  

0 个答案:

没有答案