初识React02

109 阅读3分钟

一、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/>
                密&emsp;码:<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/>
                密&emsp;码:<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、优点

  • 可以实现页面的按需加载
  • 按需加载子组件
  • 子组件可以使用相对路径,来继承父组件的前缀 {/* 相对路径的写法 /} {/ 相对路径的写法 */}