"POP"
action这个属性左右很大,如果是通过Link标签或者在js中通过this.props.push方法来改变当前的url,那么在新组件中的action就是"PUSH",否则就是"POP".
action属性很有用,比如我们在做翻页动画的时候,前进的动画是SlideIn,后退的动画是SlideOut,我们可以根据组件中的action来判断采用何种动画:
function newComponent (props)=>{
return (
<ReactCSSTransitionGroup
transitionAppear={true}
transitionAppearTimeout={600}
transitionEnterTimeout={600}
transitionLeaveTimeout={200}
transitionName={props.history.action==='PUSH'?'SlideIn':'SlideOut'}
>
<Component {...props}/>
</ReactCSSTransitionGroup>
)
}
在新组件的location属性中,就记录了从就组件中传递过来的参数,从上面的例子中,我们看到此时的location的值为:
hash: "#edit"
key: "uxs9r5"
pathname: "/home"
search: "?sort=name"
state: {a:1}除了key这个用作唯一表示外,其他的属性都是我们从上一个Link标签中传递过来的参数。
四、React-router4.0源码分析
在第三节中我们介绍了React-router的大致使用方法,读一读React-router4.0的源码。
这里我们主要分析一下React-router4.0中是如何根据window.history来实现前端路由的,因此设计到的组件为BrowserRouter、Router、Route和Link
1、React-router中的history
从上一节的介绍中我们知道,点击Link标签传递给新渲染的组件的props中有一个history对象,这个对象的内容很丰富,比如:action、goBack、go、location、push和replace方法等。
React-router构建了一个History类,用于在window.history的基础上,构建属性更为丰富的实例。该History类实例化后具有action、goBack、location等等方法。
React-router中将这个新的History类的构建方法,独立成一个node包,包名为history。
npm install history -s可以通过上述方法来引入,我们来看看这个History类的实现。
const createBrowserHistory = (props = {}) => {
const globalHistory = window.history;
......
//默认props中属性的值
const {
forceRefresh = false,
getUserConfirmation = getConfirmation,
keyLength = 6,
basename = '',
} = props;
const history = {
length: globalHistory.length,
action: "POP",
location: initialLocation,
createHref,
push,
replace,
go,
goBack,
goForward,
block,
listen
}; ---- (1)
const basename = props.basename;
const canUseHistory = supportsHistory(); ----(2)
const createKey = () =>Math.random().toString(36).substr(2, keyLength); ----(3)
const transitionManager = createTransitionManager(); ----(4)
const setState = nextState => {
Object.assign(history, nextState);
history.length = globalHistory.length;
transitionManager.notifyListeners(history.location, history.action);
}; ----(5)
const handlePopState = event => {
handlePop(getDOMLocation(event.state));
};
const handlePop = location => {
if (forceNextPop) {
forceNextPop = false;
setState();
} else {
const action = "POP";
transitionManager.confirmTransitionTo(
location,
action,
getUserConfirmation,
ok => {
if (ok) {
setState({ action, location });
} else {
revertPop(location);
}
}
);
}
}; ------(6)
const initialLocation = getDOMLocation(getHistoryState());
let allKeys = [initialLocation.key]; ------(7)
// 与pop相对应,类似的push和replace方法
const push ... replace ... ------(8)
return history ------ (9)
}
export const supportsHistory = () => {
const ua = window.navigator.userAgent;
if (
(ua.indexOf("Android 2.") !== -1 关键词:从路由开始深入理解react-router 4.0源码