React学习笔记。
练习项目:react_demo
开发工具:vscode
vscode插件:Simple React Snippets
chrome开发者插件:React Developer Tools
Hello World
环境
安装node、npm(见vue笔记)。
创建项目
1 |
//安装react脚手架(全局安装) |
编写
编写Hello World项目。
建议使用vscode开发react项目,在编写Hello World项目之前可以先安装一个插件“Simple React Snippets”。
编写组件
将src目录下的文件全部删除,在其中新建一个“App.js”文件。第一个React组件。编写内容如下:
1 |
// import React from 'react' |
可以通过更改变量mystatus、mypunctuation的值,查看页面显示效果。
添加样式
组件中html元素直接添加样式,方式如下:
1 |
<div style={{margin:'10px'}}></div> |
单独编写css样式文件,方式如下:
为组件App添加样式。在src目录下新建一个style.css文件。在其中添加css代码:
1 |
.mydiv{ |
在组件App中使用样式文件,只需要在App.js中添加语句import './style.css'
即可。
挂载组件
在src目录下新建一个“index.js”文件。用于挂载刚刚编写好的组件App。
1 |
import React from 'react' |
测试
此时打开浏览器http://localhost:3000就会看到“Hello World!”并且背景色是青色的。
固定格式
编写组件
1 |
import React, { Component } from 'react'; |
扩展:组件只能有一个根元素。若不想只有一个根元素可使用Fragment标签包裹。Fragment是react提供的,可将import修改为import
React, { Component, Fragment } from 'react'
。
挂载组件
1 |
import React from 'react'; |
函数定义
函数定义,涉及到this关键字的问题。若函数应用在事件绑定中,可能this就不是指向当前class,也就无法使用this.props.
、this.state.
。
要解决这个问题可以在绑定事件时使用bind(this)
,或constructor中声明指向当前class
1 |
//constructor中声明 |
数据更新
state中定义的变量,数据更新要使用setState函数。
不建议直接更改state里面的数据,而是通过setState去改变参数(不会重新渲染组件;性能问题)。
构造函数是唯一可以给 this.state 赋值的地方
1 |
this.setState({ |
setState函数可以接收一个回调函数,在dom渲染后调用。
父子组件
父组件
1 |
import React, { Component, Fragment } from 'react' |
子组件
1 |
import React, { Component } from 'react'; |
传值
父传子
在父组件中,使用子组件时使用参数名={父组件变量/函数/数据}
即可定义参数。在子组件中通过this.props.参数名
的方式获取相关值。
1 |
//父组件的render()中: |
子传父
子组件中不能操作父组件的数据(单向数据流),只能通过调用父组件提供的函数实现对数据的操作。
1 |
//子组件中: |
ref
1 |
// 使用 ref 将当前元素 添加/绑定 到this.myinput(当前定义的名为xjj的class的一个变量,但是不参与数据流) |
PropTypes
给父组件传递过来的参数(通过this.props.
来获取),指定其数据类型(字符串、数字、函数等),在传参时会校验,若不匹配会在控制台提示,但不影响程序运行。
在要校验参数数据类型的子组件中,导入prop-types
。
1 |
import myPropTypes from 'prop-types'; |
在class外边定义父组件传递过来的参数类型:
1 |
class xjj_item extends Component { |
生命周期
组件挂载
组件挂载mount,分为:
- 挂载前 - componentWillMount,已更名为UNSAFE_componentWillMount。已废弃,但依然可用(两个都可用)
- 挂载中 - 可以把render函数的return之前看作是挂载中
- 挂载后 - componentDidMount
若在首次渲染组件之前要获取一些数据,可以在componentDidMount生命周期函数中发起网络请求。避免组件更新时频繁获取数据。
1 |
export default class xjj extends Component { |
组件更新
组件更新update,分为:
- 更新前 - shouldComponentUpdate(nextProps, nextState),根据返回的boolean值决定是否更新组件
- 接收两个参数,即将要重新渲染的组件中的props和state
- 更新前 - componentWillUpdate,根据返回的boolean值决定是否更新组件 - 已废弃,建议使用上边的
- 更新后 -componentDidUpdate
1 |
shouldComponentUpdate(){ |
组件卸载
1 |
componentWillUnmount() { |
props
已废弃,不建议使用。
1 |
//组件第一次存在于dom中,函数是不会被执行 |
性能优化
使用生命周期钩子函数shouldComponentUpdate(组件更新前,可阻止组件重新渲染)进行性能优化。
1 |
shouldComponentUpdate(nextProps, nextState) {//组件渲染之前。接收两个参数 |
扩展:chrome开发者工具中打开React插件,在设置中勾选“Hightlight updates when components render”,可直观的看到哪些组件被渲染。
Ajax
使用Axios实现Ajax请求,Axios的安装和使用,见这篇笔记。
一般在componentDidMount生命周期函数中发起网络请求较好,可避免组件更新时频繁发起Ajax请求。
后记
仅仅使用React还远不够用来开发项目,还需要借助Redux进行数据管理、React Router进行路由管理等。
草稿
1 |
// useEffect可以看做 componentDidMount,componentDidUpdate和componentWillUnmount 这三个函数的组合 |
修改控件的默认样式
1 |
//使用.btn_box做限定,不想全局修改 |
useState
在React的函数组件中引入state。
1 |
//定义一个sate,名为matList |