一、React的生命周期函数
生命周期:指的就是React组件从创建出来到销毁的过程,我们称之为生命周期函数
React生命周期函数可以分为三个阶段:
1、挂载阶段:对象从创建到渲染的过程
2、更新阶段:组件状态发生改变
3、销毁阶段:组件在使用完之后不需要存在页面或者组件当中,就将它销毁
// 挂载阶段
export default class App extends Component{
constructor(props) {
super(props)
console.log('1.1 - 初始化一个constructor构造函数')
this.state = {
num: 24
}
}
componentWillMount() {
console.log('1.2 - 挂载前的准备阶段')
}
render() {
console.log('1.3 - 挂载渲染阶段')
}
componentDidMount() {
console.log('1.4 - 挂载完成阶段')
}
}
// 更新阶段
export default class App extends Component{
construcotr(props) {
super(props)
this.state = {
num: 24
}
}
UNSAFE_componentWillReceiveProps(nextProps) {
console.log('2.0 - 更新获取props属性阶段')
console.log(nextProps)
}
shouldComponentUpdate(nextProps, nextState) {
console.log('2.1 - 更新前判断数据是否发生改变')
}
UNSAFE_componentWillUpdate() {
console.log('2.2 - 更新前的准备阶段')
}
render() {
console.log('2.3 - 更新渲染阶段')
}
componentDidUpdate() {
console.log('2.4 - 更新阶段完成')
}
}
// 销毁阶段
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
num: 24
}
}
componentWillUnmount() {
console.log('3.1 - 销毁前对数据进行一些回收处理')
}
}
二、不受控组件和受控组件
1、不受控组件
组件的表单元素没有绑定value值,是通过 ref属性来获取DOM,不受state管理
//不受控组件
import React, { Component } from 'react'
export default class App4 extends Component {
handleClick(){
console.log(this.refs.username.value)
console.log(this.refs.password.value)
}
render() {
return (
<div>
{/* 这种组件和组件本身state数据没有关系,所以不受组件管理,称为不受控组件(无约束组件)*/}
{/* 这种写法的每个表单元素的验证在登录按钮的点击事件完成,用户体验很差 */}
用户名:<input type="text" ref="username"/> <br/> <br/>
密 码:<input type="text" ref="password"/><br/> <br/>
<button onClick={this.handleClick.bind(this)}>登录</button>
</div>
)
}
}
2、受控组件
组件的表单元素中value值受到state管理,并且该表单元素中有onChange事件
//受控组件
import React, { Component } from 'react'
export default class App4 extends Component {
constructor(props){
super(props)
this.state = {
value:"admin"
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(e){
this.setState({
value:e.target.value
})
}
render() {
return (
<div>
用户名:<input type="text" value={this.state.value} onChange={this.handleChange}/> <br/> <br/>
密 码:<input type="text" /><br/> <br/>
<button>登录</button>
</div>
)
}
}
三、路由原理
路由原理:
1、定义视图
2、定义路由
3、检测哈希值的改变
4、通过哈希值来加载对应的视图
<body>
<ul>
<li><a href="#/list">列表页</a></li>
<li><a href="#/detail">详情页</a></li>
</ul>
<div class="box"></div>
</body>
</html>
<script>
let router = {
'#/list': './list.html',
'#/detail': './detail.html'
}
window.addEventListener('hashchange', () => {
console.log(location.hash)
console.log(router[location.hash])
$('.box').load(router[location.hash])
})
</script>
四、React路由搭建
1、安装路由
npm i react-router@3.2.0 / yarn add react-router@3.2.0
2、引入路由
export { Router, Route, hashHistory } from 'react-router'
3、配置路由器
const router = <Router history={hashHistory}>
<Route path="/app" component={视图组件名}></Route>
</Router>
ReactDom.render (
router,
document.getElementById('root')
)
五、嵌套路由
1、可以在Route中嵌套子路由
const router = <Router history={hashHistory}>
<Route path="/app" component={视图组件名}>
<Route path="/app/index" component={视图组件名}></Route>
<Route path="/app/list" component={视图组件名}></Route>
</Route>
</Router>
ReactDom.render (
router,
document.getElementById('root')
)
2、子组件视图使用this.props.children来获取子组件
<div>
<h1>我是顶级组件</h1>
<ul>
<li><a href="#/app/index">去往首页</a></li>
<li><a href="#/app/list">去往列表页</a></li>
</ul>
<hr/>
{this.props.children}
</div>
3、优点
- 可以实现页面的按需加载
- 按需加载子组件
- 子组件可以使用相对路径,来继承父组件的前缀 {/* 相对路径的写法 /} {/ 相对路径的写法 */}