手挽手带你学React入门二档,组件开辟的最先,合理应用生命周期和组件,能够让你的开辟变地流畅又happy,这篇文章带你学会建立组件,应用组建。学起来吧!
React 组件生命周期
进修React,生命周期很主要,我们相识完生命周期的各个组件,对写高机能组件会有很大的协助.
我们先来看一张图
组件初始化的时刻
1、getDefaultProps()
设置默许的props,也能够用dufaultProps设置组件的默许属性.
2、getInitialState()
在运用es6的class语法时是没有这个钩子函数的,能够直接在constructor中定义this.state。此时能够接见this.props
3、componentWillMount()( 谢谢原罪大神: 此声明周期在react16已被烧毁,到17直接删除)
组件初始化时只挪用,今后组件更新不挪用,全部生命周期只挪用一次,此时能够修正state。
4、 render()
react最主要的步骤,建立假造dom,举行diff算法,更新dom树都在此举行。此时就不能变动state了。
5、componentDidMount()
组件衬着以后挪用,只挪用一次。
组件更新的时刻
6、componentWillReceiveProps(nextProps)( 谢谢原罪大神: 此声明周期在react16已被烧毁,到17直接删除)
组件初始化时不挪用,组件吸收新的props时挪用。
7、shouldComponentUpdate(nextProps, nextState)
react机能优化异常主要的一环。组件吸收新的state或许props时挪用,我们能够设置在此对照前后两个props和state是不是雷同,假如雷同则返回false阻挠更新,由于雷同的属性状况一定会天生雷同的dom树,如许就不需要制造新的dom树和旧的dom树举行diff算法对照,勤俭大批机能,尤其是在dom构造庞杂的时刻
8、componentWillUpdate(nextProps, nextState)
组件初始化时不挪用,只要在组件将要更新时才挪用,此时能够修正state,render 的时刻会用你变动的值,然则这内里不能挪用 this.setState(),会让你堕入死轮回
9、render()
组件衬着
10、componentDidUpdate()
组件初始化时不挪用,组件更新完成后挪用,此时能够猎取dom节点。
组件卸载的时刻
11、componentWillUnmount()
组件将要卸载时挪用,一些事宜监听和定时器需要在此时消灭。
// 在我们组件第一次加载完的时刻会如许实行生命周期
export default class App extends Component {
constructor(){
super()
this.state={
}
}
// getDefaultProps(){
// es6 不支持这个
// console.log('1.实行getDefaultProps')
// 详细用法在下面
// }
// getInitialState(){
// es6里不用它了
// console.log('2.实行getInitialState')
// 这个实际上是上面的state 在 constructor完成
// }
componentWillMount(){
console.log('3.实行componentWillMount')
}
render() {
console.log('4.实行render')
return (
)
}
componentDidMount(){
console.log('5.实行componentWillMount')
}
}
// 接 getDefaultProps
// 在ES6里这么玩
// 另有一种弄法是ES7内里的
// static defaultProps = {
// name: 'demo'
// }; 这里我们不多讲了。。讲多了该晕了 感兴趣的加我微信 shouzi_1994
App.defaultProps = {
name: 'demo'
};
// 在我们组件更新的时刻我们举行以下生命周期
export default class App extends Component {
constructor(){
super()
this.state={
name:'test'
}
}
componentWillReceiveProps(nextProps){
// props 更新的时刻挪用
console.log('1.实行componentWillReceiveProps')
}
shouldComponentUpdate(nextProps, nextState){
console.log('2.实行shouldComponentUpdate')
// 这个需要着重强调,我们优化机能用它很主要!假如我们行将更新的东西和本来的数据雷同,return一个false就住手组件更新勤俭机能
if(nextState.name == this.state.name){
return false
}else{
return true
}
}
componentWillMount(nextProps, nextState){
// 在组件衬着前 挪用这个
console.log('3.实行componentWillMount')
}
change=()=>{
this.setState({name:'QM'})
}
render() {
console.log('4.实行render')
return (
<button onClick={this.change}>测试</button>
)
}
componentDidUpdate(){
console.log('5.实行componentDidUpdate')
}
componentWillUnmount(){
// 这个在卸载的时刻会挪用 营业逻辑写内里就好了
}
}
生命周期简朴引见就这些了,真正事情中要根据营业需求来挪用,大大增添你的开辟效力,处置惩罚你开辟中碰到的困难。
组件建立
实在我们前面的App实际上就是一个组件了,我们类比到vue内里,它就是脚手架为我们建立的App.vue 是一个根组件,我们别的组件都衬着到这个组件的内部就好了。
那末 我们怎样建立一个子组件呢?
export default class App extends Component {
constructor(){
super()
this.state={
}
}
render() {
//要想运用子组件也很简朴 用标签的情势拿进来就好了
return (
<Children />
)
}
}
//下面我们再写一个class 而且继续 Component 这就是一个组件了
class Children extends Component{
constructor(){
super()
this.state={
}
}
render(){
return(
<h1>我是子组件</h1>
)
}
}
组件传参
我们学会了怎样建立组件,那末组件怎样传参呢?这个是异常主要的东西,毕竟组件之间不能通信,那就没有建立它的意义了。
父子传参
在React中父子传参极为相似Vue 直接在标签上填写属性,然则在子组件吸收的时刻会有所不同
我们接着运用上面的代码
export default class App extends Component {
constructor(){
super()
this.state={
}
}
render() {
//要想运用子组件也很简朴 用标签的情势拿进来就好了
return (
<Children params={"我从父组件传过来"}/>
)
}
}
//下面我们再写一个class 而且继续 Component 这就是一个组件了
class Children extends Component{
constructor(){
super()
this.state={
}
}
// 经由过程这类情势 我们就能够把父组件的东西通报给子组件了,一切的属性存储在props内里,上面我们引见生命周期的时刻,也提了一下怎样建立默许props。这里我们写一下
render(){
return(
<div>
<h1>我是子组件</h1>
<h2>{this.props.params}</h2>
</div>
)
}
// 假如父组件没有通报 params 我们又想运用默许的props 那末就要运用下面的写法
}
Children.defaultProps = {
params: '我是默许的东西'
};
// 设置了默许props今后 假如我们不传参就会默许展现我们默许规定好的属性了
插槽(相似Vue solt)
为何要把插槽放在这里解说呢?实际上React的插槽是经由过程传参的情势下来的,怎样明白呢?我以为放进代码中是最轻易明白的。
export default class App extends Component {
constructor(){
super()
this.state={
}
}
render() {
//要想运用子组件也很简朴 用标签的情势拿进来就好了
return (
<Children params={"我从父组件传过来"}>
<div>通报第一个</div>
<div>通报第二个</div>
<div>通报第三个</div>
</Children>
)
}
}
//下面我们再写一个class 而且继续 Component 这就是一个组件了
class Children extends Component{
constructor(){
super()
this.state={
}
}
// 经由过程这类情势 我们就能够把父组件的东西通报给子组件了,一切的属性存储在props内里,上面我们引见生命周期的时刻,也提了一下怎样建立默许props。这里我们写一下
render(){
console.log(this.props)
// {children:Array(3)
// params:"我从父组件传过来"}
// children的内容为 [
// {$$typeof: Symbol(react.element), type: "div", key: null, ref: null, props: {…}, …},
// {$$typeof: Symbol(react.element), type: "div", key: null, ref: null, props: {…}, …},
// {$$typeof: Symbol(react.element), type: "div", key: null, ref: null, props: {…}, …}
// ]
//我们能够看到 他们被递次放到了 this.props.children中 而且 这是个数组 内部存储的就是假造dom
return(
<div>
<h1>我是子组件</h1>
{/* 这里我用轮回的体式格局把三个children取出来直接衬着即可 */}
{this.props.children.map((item,key)=>{
return item
})}
{/* 我们越发直观一点 */}
{this.props.children[1]}
{this.props.children[0]}
{this.props.children[2]}
{/* 看到这里人人应当能够晓得插槽的简朴用法了吧 */}
</div>
)
}
// 假如父组件没有通报 params 我们又想运用默许的props 那末就要运用下面的写法
}
Children.defaultProps = {
params: '我是默许的东西'
};
子传父参
在Vue中我们能够经由过程定义函数,以实参的情势通报,在父组件捕捉的情势来猎取想要通报的参数,那末在React中这个要领是不是也一样实用呢?答案是一定的,依旧是经由过程父组件声明函数,通报给子组件,子组件挪用并传入参数,在父组件捕捉即可。
export default class App extends Component {
constructor(){
super()
this.state={
myPatams:"test"
}
}
getParams(params){
console.log(params,this)
this.setState({
myPatams:params
})
}
render() {
//要想运用子组件也很简朴 用标签的情势拿进来就好了
return (
<div>
{this.state.myPatams}
<Children params={"我从父组件传过来"} getParams={this.getParams.bind(this)}></Children>
{/* 这里我们把函数通报下去,一定要bind this 否则在我们在子组件中运用bind来挪用的时刻,this的指向会跑到子组件中 我们拿到的参数意义就不大了 固然箭头函数也是完整没题目的 */}
</div>
)
}
}
//下面我们再写一个class 而且继续 Component 这就是一个组件了
class Children extends Component{
constructor(){
super()
this.state={
}
}
render(){
return(
<div>
<h1>我是子组件</h1>
<button onClick={this.props.getParams.bind(this,"我是子传过来的参数")}>子传父参</button>
{/* 我们在这里挪用父组件通报过来的要领,而且传入参数 */}
</div>
)
}
}
Children.defaultProps = {
params: '我是默许的东西'
};
非父非子传参(events 要领)
这类非关联型组件传参平常运用redux来传参,这里我们另有没进修到,我们借助node的EventEmitter也能够轻松完成
import React,{Component} from 'react'
// 起首我们建立一个监听器
import EventEmitter from 'events'; //事宜监控对象
let emitter = new EventEmitter; //建立一个事宜监控者 一般级别的监听
emitter.setMaxListeners(100000); //设置监控管理器的最大监听数目
export default class App extends Component {
constructor(){
super()
this.state={
myPatams:"test"
}
}
getParams(params){
console.log(params,this)
this.setState({
myPatams:params
})
}
render() {
//要想运用子组件也很简朴 用标签的情势拿进来就好了
return (
<div>
{this.state.myPatams}
<Children params={"我从父组件传过来"} getParams={this.getParams.bind(this)}></Children>
{/* 这里我们把函数通报下去,一定要bind this 否则在我们在子组件中运用bind来挪用的时刻,this的指向会跑到子组件中 我们拿到的参数意义就不大了 固然箭头函数也是完整没题目的 */}
<ChildrenTwo />
</div>
)
}
}
//下面我们再写一个class 而且继续 Component 这就是一个组件了
class Children extends Component{
constructor(){
super()
this.state={
emit:""
}
}
componentWillMount(){
emitter.on('childrenEmit',(param)=>{ //我们在这里设置监听
console.log(param)
this.setState({
emit:param
})
})
}
render(){
return(
<div>
<h1>{this.state.emit}</h1>
<button onClick={this.props.getParams.bind(this,"我是子传过来的参数")}>子传父参</button>
{/* 我们在这里挪用父组件通报过来的要领,而且传入参数 */}
</div>
)
}
}
class ChildrenTwo extends Component{
constructor(){
super()
this.state={
}
}
gaveParams(param){
emitter.emit('childrenEmit',param) //从第二个子组件触发而且通报参数
}
render(){
return(
<div>
<h1>我是子组件</h1>
<button onClick={this.gaveParams.bind(this,"我是ChildrenTwo传过来的参数")}>非父非子传参</button>
</div>
)
}
}
组件抽离
写了这么多,置信人人差不多会写本身的组件而且在组件中通报参数了,这里另有一个题目,人人是不是是发明我的一切组件都写在了一个JS内部,如许假如是一个大项目,我们的这个JS就会变地异常痴肥,这时刻我们就要抽离这个组件。实际上异常简朴,用到的就是我们ES6的 export 导出 即可 假如只要一个组件 那末 还能够像我们誊写App这个基本组件一样 运用 export default 默许导出
这里我给人人抽离一下
// App.js
import React,{Component} from 'react'
import {Children} from './components/Children.js' // 由于我们的Children中运用的是 export 来暴露
//import Children from './components/Children.js' // 假如运用的是 export default 则应当如许写
export default class App extends Component {
constructor(){
super()
this.state={
myPatams:"test"
}
}
getParams(params){
console.log(params,this)
this.setState({
myPatams:params
})
}
render() {
//要想运用子组件也很简朴 用标签的情势拿进来就好了
return (
<div>
{this.state.myPatams}
<Children params={"我从父组件传过来"} getParams={this.getParams.bind(this)}></Children>
{/* 这里我们把函数通报下去,一定要bind this 否则在我们在子组件中运用bind来挪用的时刻,this的指向会跑到子组件中 我们拿到的参数意义就不大了 固然箭头函数也是完整没题目的 */}
</div>
)
}
}
// children.js
import React,{Component} from 'react'
// 当我们抽离出来今后 必需要再次引入 react的必要组件
export class Children extends Component{ //我们这里运用的是export来暴露 假如只要一个组件 也能够运用 export default 来暴露
constructor(){
super()
this.state={
}
}
render(){
return(
<div>
<h1>我是子组件</h1>
<button onClick={this.props.getParams.bind(this,"我是子传过来的参数")}>子传父参</button>
{/* 我们在这里挪用父组件通报过来的要领,而且传入参数 */}
</div>
)
}
}
Children.defaultProps = {
params: '我是默许的东西'
};
功德圆满了 代码是不是是清楚多了??
总结
这一期内容不多 主如果引见组件的生命周期 运用要领 以及怎样传参,这些内容可全都是干货,事情中会常常常常运用到,愿望人人能本身写小demo来熟习一下写法,下一期将会带人人进修React-Router 以及context和高阶组件的建立,为我们进修Redux打下基本