写给vue转react的同志们(1)

9,404

本系列文章将由浅慢慢深入,一步步带你领略react和vue的同工异曲之处,让你左手react,右手vue无忧。

学习一个框架最好的办法就是从业务做起。首先我们要弄清做业务需要什么知识点去支持

今天的主题:

  1. react 是怎么样传输数据的
  2. react 怎么封装组件
  3. react 的生命周期

实际上vue熟练的同学们,我觉得转react还是比较好上手的,就是要适应他的纯js的写法以及jsx等,个人认为还是比较好接受的,其实基本上都一样,只要弄清楚数据怎么传输怎么处理,那剩下的jsx大家都会写了吧。

react 组件通讯

这里我们来跟vue对比一下。比如 在vue中父子组件传值(简写):

// 父组件
data: {
	testText:'这是父值'
}
methods:{
	receive(val) {
		console.log('这是子值:', val)
	}
}
<child :testText="testText" @childCallBack="receive"/>
// 子组件
props: {
	testText: {
		type: String,
		default: ''
	}
}
methods:{
	handleOn(){
		this.$emit('childCallBack', '我是子组件')
	}
}
<template>
	<div @click="handleOn">{{testText}}</div>
</template>

在react中父子组件传值:

// 父组件
export default class Father extends React.Component {
   constructor(props) {
        super(props)
        this.state = {
        	testText: '这是父值'
        }
        receive = (val) => {
        	console.log('这是子值:', val)
        }
        render(){
        	return(
        		<div>
        			<Son childCallBack={this.receive} testText={testText}/>
        		</div>
        	)
        }
    }
}
// 子组件
export default class Son extends React.Component {
	constructor(props) {
        super(props)
    }
    render() {
    	const { testText } = this.props
        return (
            <div>
                父组件传过来的testText:{testText}
                <div onClick={this.receiveFather}>
                    点我从子传父
                </div>
            </div>
        )
    }
    receiveFather = () => {
        this.props.childCallBack('我是子组件')
    }
}

可以看到react 和 vue 其实相差不大,都是通过props去进行父传子的通讯,然后通过一个事件把子组件的数据传给父组件。聪明的同学肯定注意到react里我用了箭头函数赋给了一个变量了。如果不这样写,this的指向是不确定的,也可以在标签上这样写this.receiveFather.bind(this),不过这样写的坏处就是对性能有影响,可以在constructor中一次绑定即可。但还是推荐箭头函数的写法。(封装组件其实跟这个八九不离十了,就不再叙述)

react 单向数据流

我们都知道vue里直接v-model 然后通过this.属性名就可以访问和修改属性了,这是vue劫持了get和set做了依赖收集和派发更新,但是react里没有这种东西,你不能直接通过this.state.属性名去修改值,需要通过this.setState({"属性名":"属性值"}, callback(回调函数)),你在同一地方修改属性是没办法立刻拿到修改后的属性值,需要通过setState的回调拿到。我还是比较喜欢vue的双向绑定(手动狗头)。

react 的生命周期

我们都知道vue的生命周期(create、mounted、update、destory),其实react也差不多,他们都是要把某个html的div替换并挂载渲染的。 列举比较常用的:

constructor() constructor()中完成了React数据的初始化,它接受两个参数:props和context,当想在函数内部使用这两个参数时,需使用super()传入这两个参数。这个就当于定义初始数据,熟悉vue的同学你可以把他当成诸如data、methods等。 注意:只要使用了constructor()就必须写super(),否则会导致this指向错误。

componentWillMount() componentWillMount()一般用的比较少,它更多的是在服务端渲染时使用。它代表的过程是组件已经经历了constructor()初始化数据后,但是还未渲染DOM时。这个相当于vue的created啦,vue中可以通过在这个阶段用$nextTick去操作dom(不建议),不知道react有没有类似的api呢?

componentDidMount() 组件第一次渲染完成,此时dom节点已经生成,可以在这里调用ajax请求,返回数据setState后组件会重新渲染,这个就相当于vue的mounted阶段啦。

componentWillUnmount () 在此处完成组件的卸载和数据的销毁。这个相当于vue中的beforeDestory啦,clear你在组件中所有的setTimeout,setInterval,移除所有组建中的监听 removeEventListener。

componentWillUpdate (nextProps,nextState) 组件进入重新渲染的流程,这里可以拿到改变后的数据值(相当于vue中beforeupdated)。

componentDidUpdate(prevProps,prevState) 组件更新完毕后,react只会在第一次初始化成功会进入componentDidmount,之后每次重新渲染后都会进入这个生命周期,这里可以拿到prevProps和prevState,即更新前的props和state,(相当于vue中的updated)。

render() render函数会插入jsx生成的dom结构,react会生成一份虚拟dom树,在每一次组件更新时,在此react会通过其diff算法比较更新前后的新旧DOM树,比较以后,找到最小的有差异的DOM节点,并重新渲染。这里就是你写页面的地方。

总结

小细节

  1. react 中使用组件第一个字母需大写
  2. react 万物皆可 props
  3. mobx 很香🐶
  4. react中没有指令(如v-if、v-for等)需自己写三目运算符或so on~

总结一下,从vue转react还是比较好上手的(react中还有函数式写法我没有说,感兴趣可以看看),个人认为弄清楚数据通讯以及生命周期对应的钩子使用场景等,其实基本就差不多啦。但是还有很多细节需要同学们在实际业务中去发现和解决。react只是框架,大家js基础还是要打好的。祝各位工作顺利,准时发薪。🐶