React-router 4
介绍了在router4以后,如何去实现按需加载Component,在router4以前,我们是使用getComponent的的方式来实现按需加载的,router4中,getComponent方法已经被移除,下面就介绍一下react-router4是入围和来实现按需加载的。
1.router3的按需加载方式
require.ensure([],require => {
cb(null,require('../Component/about').default)
},'about')
}
//配置route
2.router4按需加载方式(three steps)
one step:
创建Bundle.js文件,这个文件其实是个通过bundle-loader包装后的组件来使用,下面会具体讲这个东西。
state = {
// short for "module" but that's a keyword in js,so "mod"
mod: null
}
componentWillMount() {
// 加载初始状态
this.load(this.props);
}
componentWillReceiveProps(nextProps) {
if (nextProps.load !== this.props.load) {
this.load(nextProps);
}
}
load(props) {
// 重置状态
this.setState({
mod: null
});
// 传入组件的组件
props.load((mod) => {
this.setState({
// handle both es imports and cjs
mod: mod.default ? mod.default : mod
});
});
}
render() {
// if state mode not undefined,The container will render children
return this.state.mod ? this.props.children(this.state.mod) : null;
}
}
Bundle.propTypes = {
load: PropTypes.func,children: PropTypes.func
};
export default Bundle;
second step:
third step:
Welcome!
3.router4按需加载方方式解析
(1).首先解释一下按需加载,通俗的将就是我当前的location在Home,那么我只应该加载Home的东西,而不应该去加载About等等其他的。
(2).Bundle.js这个文件的作用
先看这段代码:
这里是我们通过import loadDashboard from 'bundle-loader?lazy!./containers/A'这种方式引入的container控件。我们使用了bundle-loader将A的源码转化成了上面的代码,具体实现大家可以看bundle-loader源码,代码很少。
上面说到Bundle.js其实就使用来处理这个文件的,这个文件需要一个callback的参数,在Bundle的load方法中,我们会设置这个callback,当路由要调到A Container这里的时候,就回去加载A Container,然后调用这个callback,这个callback会调用setState方法,将我们之前传入的load设置给mod,然后渲染出来。
4.webpack进行bundle-loader统一配置
这里匹配的是src/routers/下面的containers文件夹下面所有的js文件,包括二级目录。
5.部分源码
1.bundle-loader的源码
module.exports = function() {};
module.exports.pitch = function(remainingRequest) {
this.cacheable && this.cacheable();
var query = loaderUtils.getoptions(this) || {};
if(query.name) {
var options = {
context: query.context || this.options.context,regExp: query.regExp
};
var chunkName = loaderUtils.interpolateName(this,query.name,options);
var chunkNameParam = "," + JSON.stringify(chunkName);
} else {
var chunkNameParam = '';
}
var result;
if(query.lazy) {
result = [
"module.exports = function(cb) {\n"," require.ensure([],function(require) {\n"," cb(require(",loaderUtils.stringifyRequest(this,"!!" + remainingRequest),"));\n"," }" + chunkNameParam + ");\n","}"];
} else {
result = [
"var cbs = [],\n"," data;\n","module.exports = function(cb) {\n"," if(cbs) cbs.push(cb);\n"," else cb(data);\n","}\n","require.ensure([]," data = require(",");\n"," var callbacks = cbs;\n"," cbs = null;\n"," for(var i = 0,l = callbacks.length; i < l; i++) {\n"," callbacksi;\n"," }\n","}" + chunkNameParam + ");"];
}
return result.join("");
}
/*
Output format:
var cbs = [],data;
module.exports = function(cb) {
if(cbs) cbs.push(cb);
else cb(data);
}
require.ensure([],function(require) {
data = require("xxx");
var callbacks = cbs;
cbs = null;
for(var i = 0,l = callbacks.length; i < l; i++) {
callbacksi;
}
});
*/
2.A的源码
class A extends BaseContainer {
constructor(props) {
super(props);
this.renderCustom = function renderCustom() {
return (
A.propTypes = {
dispatch: PropTypes.func,};
function mapStatetoProps(state) {
return { state };
}
3.route.js的源码
const app = () =>
);
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。