1. 组件挂载、JSX 变量引用
index.js 中
// 1.引入模块
import React from 'react'
import { createRoot } from 'react-dom/client'
//2.引入组件
import App from './App'
//3.将组件挂载到指定元素上
const root = createRoot(document.getElementById('root'));
root.render(
<div>
<App/>
</div>
)
App.js 中
import React,{ Component } from 'react'
const name = '小米';
//JSX 中引用变量
export default class App extends Component {
render(){
return(
<p>{name}</p>
)
}
}
2. 三目运算符、for循环
import React, { Component } from 'react'
const name = '小米', num = '123', gender = '1', arr = ['孙悟空', '唐三藏', '猪八戒', '沙悟净', '白龙马']
const logoUrl = require('./assets/logo192.png')
const imgUrl = require('./assets/123.png')
// style接受一个采用小驼峰命名属性的 JavaScript 对象,实现动态样式
let bgStyle = {
color: 'red',
width: '200px',//等同于 width:200 React 会自动添加 ”px” 后缀到内联样式为数字的属性后。
height: '200px',
backgroundImage: 'url(' + imgUrl + ')'
}
function a(params='') {
if(true){
return params
}
}
let b = a('66666')
export default class HI extends Component {
render() {
return (
<>
{/* 这是注释的格式 */}
{/* JSX中引用表达式使用花括号 */}
<hr />
<div>{name}</div>
<div>有{num}个饼干</div>
<h2>It is {new Date().toLocaleTimeString()}</h2>
<img src={logoUrl} alt="" />
{/* 三元运算符 */}
<div>{gender === '0' ? '男性' : gender === '1' ? '女性' :
'儿童'}</div>
<ul>
{/* 遍历 */}
{/* 第一种写法,小括号 */}
{arr.map((i, k) => (<li key={k}>{i}</li>))}
</ul>
<ul>
{/* 第二种写法,大括号 + return */}
{
arr.map((i, k) => {
return <li key={k}>{i}</li>
})
}
{/* 多层嵌套时,key的位置:在 map() 方法中的元素需要设置 key 属性作为标识。
*/}
</ul>
<div style={bgStyle}>
哈哈哈 {b}
</div>
</>
)
}
}
3.组件传值
父传子:
子组件通过 this.props 属性接收父组件传过来的值。
子传父:
子级通过 this.props.子级事件名(参数) 将事件传递给父级,父级在子组件标签上写:<tag 子级事件名={this.父组件事件名.bind(this)}></ tag>。
Sub.js 中 (子组件)
import React, { Component } from 'react'
import propTypes from 'prop-types'
export default class Sub extends Component {
// static 定义静态属性值
static defaultProps = {
num :1001
}
static propTypes = {
// num: propTypes.number.isRequired // isRequired表示必传,number表示数字类型
num: propTypes.number
}
render(){
return(
<div>
{/* 子组件通过 this.props 属性接收父组件传过来的值 */}
<p>{this.props.num}</p>
<button onClick={this.handleClick.bind(this)}>改变num</button>
</div>
)
}
handleClick(){
// 子级通过this.props.子级事件(参数)
this.props.subClickFn(999)
}
}
App1.js中
// 父组件
import React, { Component } from 'react'
import Sub from './Sub'
export default class App1 extends Component {
state = {
num: 123
}
render() {
return (
<div>
{/* <tag 子级事件名={this.父级事件名.bind(this)}></tag> */}
<Sub num={this.state.num} subClickFn={this.faFn.bind(this)} />
</div>
)
}
faFn(arg) {
console.log(arg); //获取子级传过来的数据
// 子传父修改num的值
this.setState({
num: arg
})
}
}
4. React 生命周期
分为三个阶段:挂载阶段、存在期/更新期、销毁期
1.挂载阶段
App3.js
import React, { Component } from 'react'
export default class App3 extends Component {
// 生命周期第一个阶段: 挂载/初始化阶段
constructor() {
console.log('1.1 构造初始化');
super()
this.state = {
// 1.1初始化数据
num: null
}
}
// componentWillMount() { //警告
UNSAFE_componentWillMount() {
alert('will do something')
console.log('1.2 预加载UNSAFE_componentWillMount');
// 1.2做一些准备性工作,比如提示正在加载
}
componentDidMount() {
console.log('1.4 异步加载 componentDidMount');
// 1.4 异步加载,比如请求数据等等
}
render() {
console.log('1.3 渲染render');
return (
<div>
<button onClick={this.handleClick.bind(this, 1)}>点击了1</button>
<button onClick={this.handleClick.bind(this, 2)}>点击了2</button>
</div>
)
}
handleClick(num) {
console.log('点击了' + num);
}
}
- 存在期/更新期
App3.js
import React, { Component } from 'react'
class App3 extends Component {
// 生命周期第一个阶段: 挂载/初始化阶段
constructor() {
console.log('1.1 构造初始化');
super()
this.state = {
// 1.1初始化数据
num: null
}
}
// componentWillMount() { //警告
UNSAFE_componentWillMount() {
alert('will do something')
console.log('1.2 预加载UNSAFE_componentWillMount');
// 1.2做一些准备性工作,比如提示正在加载
}
componentDidMount() {
console.log('1.4 异步加载 componentDidMount');
}
render() {
console.log('1.3 渲染render');
return (
<div>
<button onClick={this.handleClick.bind(this, 1)}>点击了1</button>
<button onClick={this.handleClick.bind(this, 2)}>点击了2</button>
<button onClick={this.handleClick.bind(this, 3)}>点击了3 num:{this.state.num}</button>
<div>接收父级传的值fatherNum :{this.props.fatherNum}</div>
</div>
)
}
handleClick(num) {
console.log('点击了' + num);
this.setState({
num: 666
})
}
// 生命周期第二个阶段 存在期/更新期
UNSAFE_componentWillReceiveProps(nextProps) {
// 这个方法props属性值更新的时候才会执行,更新state数据则不会执行这个方法
console.log("2.6 componentWillReceiveProps nextProps")
}
/**
* @description: 根据接收值的改变来决定是否---render更新组件
* @return {*} false则不执行render; true则执行render
* @param {*} nextProps 接收的props父组件数据
* @param {*} nextState 组件内部的state值
*/
shouldComponentUpdate(nextProps, nextState) {
//旧的值:this.state.num 新的值nextState.num 通过判断新旧值是否一样,不一样才执行render。减少不必要的render,优化性能
// render false 则不执行render
// render true 则执行render
// return this.state.num !== nextState.num
if (this.state.num !== nextState.num) { //不一样则执行render
console.log('2.1 shouldComponentUpdate nextState');
return true
} else if (this.state.num !== nextProps.num) {
console.log('2.7 shouldComponentUpdate nextProps');
return true
} else {
console.log('2.1.1 不需要重新render');
return false
}
}
UNSAFE_componentWillUpdate(nextProps, nextState) {
console.log('2.3 componentWillUpdate 更新前');
}
componentDidUpdate(prevProps, prevState) {
console.log('2.4 componentDidUpdate 更新后');
}
}
export default class App3Father extends Component {
constructor(props) {
super(props)
this.state = {
fatherNum: 0
}
}
render() {
return (
<div>
<App3 fatherNum={this.state.fatherNum} />
</div>
)
}
componentDidMount() {
this.timer = setTimeout(() => {
this.setState({
fatherNum: 10
})
console.log('2.5 修改了父级的fatherNum的值');
}, 2000)
console.log("------------------------------------------")
}
}
App3.js
...
// 生命周期第三个阶段 卸载期/销毁期
componentWillUnmount() {
clearTimeout(this.timer)
console.log("3.1 componentWillUnmount 做一些回收的操作")
}
总结,
componentDidMount : 发送ajax异步请求
shouldComponentUpdate : 判断props或者state是否改变,目的:优化更新性能
componentWillUnmount : 销毁定时器、事件监听器等