react特点:
1、声明式
命名式:当想要做什么事时需要告诉计算机你要干什么,怎么做
声明式:当想要做什么事时只需告诉计算机你想干什么,不用管怎么做的
* 大部分ES5的方法都是声明式,例如forEach、map等,只需要会用,不用管内部怎么实现的
2、组件:灵活、复用
3、虚拟DOM:提高性能
4、完整的全家桶
vue:vue+vue-router+vuex+vue-touch+elementUI。。。
react:react+react-dom+react-router+redux+react-redux+antd。。。
5、单向数据流
vue:Object.defineProperty() 双向响应式数据流
react:redux(观察者模式) 单向响应数据流
6、函数式编程
概念:函数式编程是一种思想
特点:
①声明式
②纯函数:输入一定输出也一定,不改变原数据的方法一般都是纯函数,map()是纯函数,forEach()不是纯函数
③柯里化函数(react高阶组件):将多个参数的函数转化成一个参数的函数。面试题:实现一个函数add(2)(3)(5)的结果为10
function add(a){ return function(b){ return function(c){ return a+b+c } } } let add=a=>b=>c=>a+b+c
④反柯里化函数
7、jsx语法
vue:template语法
react:jsx语法(允许在js中写html代码) ps:因为要写jsx语法,但是浏览器不支持jsx语法,需要下载 @babel/preset-react 插件
8、react和vue的区别
react的灵活度比vue高,vue的上手速度较快
react是单向响应式数据流,vue是双向响应式数据流
react用的是jsx语法,vue用的是template语法
9、面试题
react中的性能优化
react中如何做数据的更改
this.setState()的理解
this.setState()中第二个参数的作用
this.setState()是同步的还是异步的,什么时候是同步的,什么时候是异步的,为什么是异步的
下载插件和启动:
下载插件:
npm i @babel/preset-react webpack-dev-server -D npm i react react-dom
react是react的核心语法,react-dom是用来解析jsx的语法
启动:在原来的webpack搭的架子里执行npm run dev,localhost:9001打开页面
ReactDOM的参数:
ReactDOM.render(<App />, document.getElementById('root'), () => {
console.log('启动react')
})
参数一:需要渲染的节点或组件
参数二:将渲染好的DOM节点放到哪个根节点上
参数三:成功的回调
jsx语法需要注意的地方:
class必须要写成className,因为class是关键字
<label htmlFor='username'></label> label中的for要写成htmlFor,for是循环的关键字
react中组件的创建:
1、组件的名称必须要大写(App),为了区分组件和标签
2、通过ES6的继承实现组件的创建,继承与React.Component
3、组件内部必须要有一个render函数,render函数中必须返回一个jsx语法(jsx中只能有一个根节点,可以写成<></>或<Fragment></Fragment>都不会渲染成dom)
4、组件中constructor是选填的,constructor用来做组件的初始化;存放组件需要的一些状态,如果需要存放必须要写在constructor中的this.state中;如果写了constructor必须要写super(),不写的话this指向不正确
import React, { Fragment } from 'react' // Fragment:react内置组件,用来做容器盒子,不会被渲染到页面上 class App extends React.Component { // constructor是用来做组件的初始化 constructor() { super() // constructor中必须要写super(),不写的话this指向会发生错误 this.state = { name: '小华' } } render() { let { name } = this.state return ( <div className="app"> <h1>App</h1> </div> ) } } export default App
react中的事件:
语法:给元素添加 on事件名 (事件首字母必须要大写,原生中可以小写也可以大写)= {事件函数}
第一种:(需要传参)
<h2 onClick={this.handleClick.bind(this,'wxm')}></h2>
第二种:(不需要传参)
constructor(){ super() this.handleClick=this.handleClick.bind(this) // 初始化 } <h2 onClick={this.handleClick}></h2>
第三种:(少见,ui层和逻辑层未分离)
<h2 onClick={()=>{console.log('xxxxxxxxxx')}}></h2>
注意事项:
1、react中的事件函数不要加(),加了就是自动执行的意思
2、react中的事件函数默认情况下this的指向是undefined,如果需要将this指向为当前组件需要通过bind绑定
3、因为render函数会多次执行,因此bind绑定的时候可以放在constructor中。当需要传参时在render函数内部的事件中bind,不需要传参可以在constructor中进行bind(this.handleClick=this.handleClick.bind(this))
this.setState():
语法:
第一种:
this.setState({ key:value },()=>{})
第二种:
this.setState(()=>({ key:value }),()=>{})
1、在react中,如果需要修改state中的值,必须要通过this.setState()修改
2、this.setState()是异步的
3、this.setState()中的第二个参数是一个回调函数。作用:①验证数据是否修改成功②可以获取数据更新后最新的dom结构
4、只要this.setState()执行了那么render函数就会执行
组件传值:
父传子:
传递:给子组件标签上绑定一个自定义属性,值为需要传递的数据
<One username={this.state.name}></One>
接收:在子组件render函数中通过props接收
let { username } = this.props
子传父:
传递:在子组件中通过 this.props.事件函数 来进行传值
<button onClick={this.handleAdd.bind(this)}>点击发送给父组件</button>
handleAdd() { this.props.toApp('我是从two组件传来的') }
接收:在子组件标签上绑定一个自定义属性,值为需要接收参数的函数
<Two toApp={this.handle2.bind(this)}></Two> handle2(value) { this.setState({ towValue: value }) }