1、react设置的初衷就是为了帮助用户高效的更新浏览器DOM,可以不需要再直接操作DOM,取而代之的是去操作React元素(虚拟DOM,实质是JS对象,表示如何创建浏览器DOM的一组指令)
(1)创建一个React元素
使用工厂类:第一个参数代表元素属性,第二个参数代表子节点
使用createElement方法
第一个参数代码我们希望创建的元素的类型,第二个参数代表元素含有的一些特性(属性),第三个参数即以后的参数代表元素的子节点,也可以是React元素,这些子节点最终都会被放进props.children中。
执行React.creatElement()方法实际产生下面对象:
(2)渲染一个React元素成为DOM元素
第一个参数是我们希望渲染的React元素,第二个参数是目标节点,即渲染的具体位置。
2、使用React的好处:可以将UI和数据分离,React只包含JS,可以添加JS的业务逻辑来构建React组件树。例如在React中使用map函数(绑定key是为了辅助React更高效地更新DOM)
3、React创建组件的3种方法(导入组件的时候开头要大写!)
可以在组件中添加传值类型检查,默认值等功能。
(1)createClass函数(react3.0以后已抛弃这种用法)
(2)ES6类语法(支持继承的自定义组件类)
(3)无状态函数组件(创建一个返回react元素的纯函数)
4、JSX: JSX其实是React.createElement的简化版。
JSX还可以和组件一起使用:
JSX不能直接在浏览器运行,可以用babel转译成JS语法,引用CDN,对type为text/babel类型的script转译。
5、组件自定义事件与ref:
this.submit = this.submit.bind(this)可以让submit方法的作用域变成这个组件的作用域
在JSX语法中用ref定义标识符后,React就能通过标识符访问DOM。
6、翻转数据流(子组件的数据传到父组件中,即数据的双向绑定)
在父组件中定义一个函数属性:
(1)在自定义组件类中使用:
在子组件某触发函数中执行这个之前定义的函数:
(2)在无状态组件函数中使用:
先解构对象获得之前定义的方法
然后在某个触发函数中直接执行这个函数
7、在函数组件中DOM绑定事件并传值给定义的函数:
8、使用useState(),使得数据变化时,组件也重新渲染
10、React的state管理:React组件中的state可以用单个JS对象表示,当某个组件的state发生变化,这个组件会渲染一个新的UI来反映这个变化。
(1)在Class中使用state
先在构造函数中初始化state
定义一个操作state的方法。只有通过调用setState方法改变state才会去更新UI
在组件中引用这个方法
(2)无状态组件函数中不能使用state
11、React生命周期
(1)挂载生命周期
①在createClass方法中:
1)getDefaultProps:获得组件的属性
2)getInitialState:来初始化state
3)componentWillMount()
4)render()
5)componentDidMount()
6)componentWillUnmount()
②在ES6类语法中不存在上述两个方法,而是获取props后传给构造函数,并在构造函数中初始化state
1)constructor(props): 来获得组件属性和初始化state
2)componentWillMount(): 在DOM被渲染前触发,用来初始化三方库,请求数据,启动动画等,还能触发setState(等到渲染完毕后触发,并更新生命周期)
3)render()
4)componentDidMount():在组件渲染完毕后触发,也是个创建API请求、初始化三方库的好地方。它里面的setState会直接启动更新生命周期。此时还可以启动intervals,timers等后台进程。
5)componentWillUnmount(): 在组件被卸载前触发
(2)更新生命周期:当组件state发生变化或从父组件接受到新属性时触发
①componentWillReceiveProps(nextProps):仅当新属性被传递给这个组件时,才会调用,在更新生命周期钩子中,只有这个可以调用setState(防止无限递归)
②shouldComponentUpdate(nextProps,nextState): 更新生命周期的门卫,可以取消更新操作。
③componentWillUpdate(nextProps,nextState): 组件更新前触发
④componentDidUodate(prevProps,prevState): 组件更新后触发
12、高阶组件(HOC):是一个简单函数,接受一个组件,然后返回一个组件(包装组件)
13、Flux,是Facebook开发的一种设计模式,旨在保持数据单向流动。
应用程序的state数据存放在React组件外部的store进行管理。用户进行操作时,一个action会被创建(包含一组指令和需要变更的目标数据)。然后Dispatcher(中央控制组件)会负责分发这个action到相应的store中。而store接受到一个action后,会修改state和更新view。Flux繁衍出很多框架,包括Flux/ReduX等等
14、Redux: 基于Flux,使用单个不可变对象表示应用程序的State 包含Action,Action生成器,Store,移出了Dispatcher。引入了Reducer:是一个纯函数,会根据当前State和Action返回一个新的State。
(1)State: 应用程序的state都放在一个对象中,且该对象不可变,只能通过整体替换的方式来更新这个State对象。
(2)Action: Action是更新State的唯一方法
这个action就包含了类型和一些载荷数据。
(3)Reducer: 是一类函数,将当前State和Action传入,创建和返回一个新的State
(4)Store:Redux只有一个Store, 通过当前的State和Action,传给单个Reducer来更新state。
①store.createStore(reducer, [initialState]),第一个参数是一个reducer函数,第二个参数是任意类型的数据,是初始化的state
②store.dispatch(action):接受一个action,然后分发到对应的Reducer上,然后更新state
③store.subscribe(fn): 接受一个函数,每次分发完毕一个action后触发。返回一个函数,执行这个返回函数就可以退订。
15、React Router;在单页面应用中,浏览器的历史记录,书签,前进,后退在没有路由转发解决方案的情况下将无法正常工作。路由转发可以标记客户端请求的内容,以便JS可以加载和渲染相应的用户界面。
(1)安装react-router-dom
(2)导出一些组件
(3)在根组件中使用Router
在Route标签中使用path=”/:id”,可以将url的参数存在match.params对象中:
在父组件中定义接受参数:
在子组件中获得这个id参数:
16、快速搭建一个react项目
(1)使用create-react-app:
①npm i -g create-react-app
②create-react-app my-project-name: 快速构建一个react项目
③npm start 运行react项目
(2)使用Ant Design Pro
①先创建一个项目文件夹proj1
②cd proj1
③npm create umi
④选择ant-design-pro,等它安装完
⑤npm i 安装依赖
⑥npm start运行项目