声明式开发
- 命令式开发:原生js和jq写代码的时候,大部分代码都是在操作dom,这种开发模式就是命令式开发。
- 声明式开发:react是面向数据编程,不需要直接去控制dom,你只要把数据操作好,react自己回去帮你操作dom,可以节省很多操作dom的代码。这就是声明式开发。
可以和其他框架并存
- react所控制的dom就是id为root的dom,页面上的其他dom元素你页可以使用jq等其他框架。所以react是可以和其他框架并存的。
组件化
- 在我们写todo-list的时候,我们已经使用react的组件了。通过继承react的Component去创建一个组件。
单向数据流
- react是单向数据流,父组件传递给子组件的数据,子组件能够使用,但是不能直接通过this.props修改。否则会报错。(cannot assign to read only property ‘xxx’ of object ‘#object’)
- 子组件要传值给父组件,或者要修改父组件的代码,都是要通过父组件传递过来的方法去实现。
- 这样的好处在于,让数据清晰代码容易维护,如果每个子组件都能直接修改父组件的数据,当子组件躲起来代码维护起来很麻烦。
react是视图层框架
- 结合上面讲的单向数据流,如果是大型项目,非常多的子组件,要修改一个公共的参数,就需要很多层的传递才能完成一个数据变更。
- 单单react去做大型项目是不够的,他优势在于视图层的渲染,涉及到复杂的数据传递,还需要结合其他数据层的框架开发。如mox-box,redux。
函数式编程
- react项目中大部分都是函数,连html都是由render函数去实现的。
- 他的优势在于,方便代码维护,复杂的函数可以拆分成多个函数。
- 在前端自动化测试也很方便,只需要给函数一个参数,看他的输出就可以了。
react开发调试工具
- react Developer Tools (需要FQ,在谷歌浏览器应用商店)
propTypes 与 DefaultProps
- value: PropTypes.string.isRequired --> value是父组件传递过来的参数,子组件规定value必须是字符串,并且必须传递(isRequired)
- deletItem: PropTypes.arrayOf(PropTypes.string,PropTypes.func) --> deletItem必须是方法,或者字符串
- 更多类型参考官方文档 -->这里就不留地址了,留地址会被锁定。
import React, {Component, Fragment} from 'react';
import PropTypes from 'prop-types'; //引入propTypes
class Item extends Component {
deletItem = () => {
const { deletItem, index } = this.props;
deletItem(index);
}
render(){
const { value } = this.props
return(
<Fragment>
<div
onClick = {this.deletItem}
>
{value}
</div>
</Fragment>
)
}
}
Item.prototypes = {
test: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,//定义传递过来的value参数必须是字符串
deletItem: PropTypes.arrayOf(PropTypes.string,PropTypes.number),// 必须是方法或者字符串的数组
deletTtem: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
]),// 必须是这些类型的中的一个。
index: PropTypes.number // 必须是数字
}
Item.defaultProps = {
test: 'defaultProps' // 为test设置默认值,如果没有传入test,就使用这个默认值
}
export default Item
Props,State 与 Render 函数之间的关系
- 数据变化为什么视图会变化?
- react的视图是通过Render函数去渲染的,组件当中,如果Props或者State有变化,Render函数就会重新执行一次。
- 父组件的Render重新执行,对应的他的子组件中的Render也会重新执行。