一、React安装
确保电脑具备nodejs环境,使用win+R 调出控制台,在默认路径下使用以下带代码:
npm i -g create-react-app //全局安装react环境无需选择特定文件夹
二、创建脚手架
调出控制台,cd 到要创建项目的目录之下,使用以下代码:
create-react-app mreact //create-react-app + 文件名 该文件名是react根文件名
创建过程可能会有些漫长,创建完成后出现如下信息:
进入到上面我们创建的mreact项目目录中,使用如下代码:
npm start //运行项目
运行成功后会自动打开浏览器并显示以下画面:
三、React简单用法
1、元素渲染
元素是构成React应用的最小单位,用于描述屏幕上输出的内容,在使用React开发时一般只会定义一个根节点,要将React元素渲染到根DOM节点中,可通过ReactDOM.render()的方法渲染元素
以上的例子中元素被创建后,无法改变其内容和属性,更新界面的办法就是创建一个新的元素,传入ReactDOM.render();
以上通过setInterval计时器方法,每秒钟调用一次tick方法,实现更新元素渲染,也可将以上要展示的元素封装起来,如下:
2.React JSX
React使用JSX代替常规的javaScript,它有执行速度快、类型安全、简单的优点,如下myDivElement的写法:
可以在JSX中使用javaScript表达式,表达式写在花括号内,JSX中不能使用if else语句,可以用conditonal(三元运算)来代替,如下:
可以使用语法来设置内联样式,如下:
JSX允许在模板中插入数组,数组会自动展开所有成员,如下:
3.React组件
第一种可使用函数定义组件,同上面使用的Clock封装方式,如下:
const element = <HelloMessage /> 为用户自定义的组件,可向组件传递参数,由props对象来获取
第二种可使用class来定义一个组件,如下:
第三种复合组件,可通过创建多个组件来合成一个组件,即把组件的不同功能进行分化,如下:
4.React State(状态)
通过与用户的交互,实现不同的状态,渲染UI,让用户界面和数据保持一致,只需更新组件的state,根据state重新渲染用户界面,手动刷新时,时间会改变,如下:
上面的constructor就是一个生命周期钩子函数,下面的例子使用了其它钩子函数,如下:
componentDidMount() 与 componentWillUnmount() 方法也被称作生命周期钩子,在组件输出到DOM后会执行componentDidMout()钩子,就可以在钩子上设定一个定时器,也称为挂载,this.timerID是定时器的ID,可以在componentWillUnmout()钩子中,在组件被卸载前卸载定时器。代码执行顺序:
当<Clock/>被传递给render()时React调用组件的构造函数constructor,创建时间对象并初始化;React然后会调用组件的render()方法,更新DOM以匹配Clock的渲染输出;当Clock的输出插入到DOM中时,React调用componentDidMount()生命周期钩子,要求浏览器创建一个定时器,每秒钟调用一次tick();在tick中,通过使用包含当前时间的独享调用setState()来调度UI更新,告诉React状态已发生改变,并再次调用render(),更新时间、DOM;一旦Clock组件从DOM中移除,React会调用componentWillunmount()钩子函数,清除定时器。
5.React Props
state和props主要的区别在于props是不可变的,而state可以根据与用户交互来改变,子组件只能通过props来传递数据。如下:
可以通过组件类的defaultProps属性为props设置默认值,程序是自上而下的,需注意设置默认值的位置,如下:
以下实例演示了如何组合使用state和props,可以在父组件中设置state,并通过在子组件上使用props将其传递到子组件上,在render函数中,设置name和site来获取父组件传递过来的数据。
6.事件处理
React事件绑定属性的命名采用驼峰式写法,如果采用JSX的语法需要传入一个函数作为事件处理函数,React中写法为: <button onClick={activateLasers}>
以下为例:
this.handleClick = this.handleClick.bind(this); 这样绑定是必须的,这样this才能在回调函数中使用,prevState.isToggleOn可替换为this.state.isToggleOn。使用 prevState 参数而不是直接引用 this.state 的原因是,setState 方法是异步的,可能会批量处理多个状态更新。通过使用 prevState,我们可以确保在更新状态时始终使用最新的值,而不受异步处理的影响。
向事件处理程序传递参数,如下:
<a href="https://reactjs.org" onClick={(e) => this.preventPop(this.state.name,e)}>Click</a>
<a href="https://reactjs.org" onClick={this.preventPop.bind(this,this.state.name)}>Click</a>
这两种方法是等价的,参数e作为React事件对象当作第二个参数传递,通过箭头函数的方式;但是通过bind的方式,事件对象以及更多的参数会被隐式的进行传输;以上还使用到了preventDefault()方法,它会阻止默认行为,在以上代码中,链接的跳转行为会被阻止。
7.条件渲染
在React中,可以创建不同的组件来封装你需要的行为,可以根据应用的变化状态只渲染其中的一部分,或是使用元素变量、运算符&&、三目运算,if else等,如下:
8.React列表和Keys
可以使用javaScript的map方法创建列表,如下:
keys可以在DOM中的某些元素是被增加或删除时帮助React识别那些元素发生了变化,一个元素最好的key是这个元素是在列表中拥有独一无二的字符串,通常使用来自数据的id作为元素的key,当没有确定的id时可以使用序列号的索引index作为key,如下:
用keys提取组件时,应把key保存在组件元素上而不是放在html元素上,如下:
Key元素应该在兄弟元素之间必须唯一,不需要全局唯一,不应该包含随机值,不会因为重新渲染而发生变化,也可以在JSX中嵌入map(),如下:
9.React组件API
setState(object nextState[, function callback]);
nextState将要设置的新状态,该状态会和当前的state合并。
callback,可选参数,回调函数,会在setState设置成功,且组件重新渲染后调用。
不能在组件内部通过this.state修改状态,因为该状态会在调用setState()后被替换,setState()并不会立即改变this.state,而是创建一个即将处理的state,setState并不一定是同步的,React会批量执行state和DOM渲染,setState()总是会触发一次组件重绘,除非在shouldComponentUpdate()中实现了一些条件渲染,如下:
forceUpdate([function callback]);
callback,可选参数,回调函数。该函数会在组件render()方法调用后调用。
forceUpdate()方法会使组件调用自身的render方法重新渲染组件,组件的子组件也会调用自己的render,但组件重新渲染时,依然会读取this.props和this.state,如果状态没有改变,那么只会更新DOM。
10.React组件的生命周期
组件的生命周期可分为三个状态:
Mounting(挂载):已插入真实DOM;Updating(更新):正在被重新渲染;Unmounting(卸载):已移出真实的DOM。常用钩子函数的触发时机和作用可参考下表:
钩子函数 | 触发时机 | 作用 |
constructor | 创建组件时,最先执行 |
|
render | 组件渲染时 | 渲染UI |
componentDidMount | 组件挂载完成渲染后 |
|
componentDidUpadte | 组件更新后 |
|
componentWillUnmount | 组件卸载前 | 执行清理操作 |
钩子函数的生命周期可参考下表:
挂载时 | 更新时 | 卸载时 |
constructor | ||
getDerivedStateFromProps | ||
shouldComponentUpdate | ||
render | ||
getSnapshotBeforeUpdate | ||
componentDidMount | componentDidUpadte | componentWillUnmount |
11.React AJAX
React组件的数据可以通过componentDidMount方法中的Ajax来获取,当从服务端获取数据时可以将数据存储在state中,再用this.setState方法重新渲染UI。当使用异步加载数据时,再组件卸载前使用componentWillUnmount来取消未完成的请求。如下:
以上组件在使用时,输入一个名为source的变量,输入请求访问地址,请求方式是jQuery完成请求,下面例子使用AJAX中的axios完成请求,如下:
12.React表单与事件
在下面的实例中,设置输入框input值value ={this.state.data},在输入框值发生改变时我们可以更新state,使用onChange事件来监听input的变化,并修改state。
下面的实例中演示如何在子组件上使用表单。需要在父组件通过创建事件句柄handleChange,并作为prop(updateSstateProp)传递到子组件上,onChange方法将组触发state的更新并将更新的值传递到子组件的输入框的value上来重新渲染UI。
在React中,不使用selected属性,而是在根select标签上用value属性来表示选中项,如下:
当有处理多个input元素时,可以通过给每个元素添加一个name属性,让处理函数根据e.target.name的值来选择做什么
通过onClick事件来修改数据: