react
CRA 搭建 React 开发环境
- 切换镜像 【可选】
切换安装镜像源,提高npx下载速度
npm config set registry https://registry.npmmirror.com/
配置后可通过下面方式来验证是否成功
npm config get registry
不成功可以:npm i nrm -g open@8.4.2 --save
- nrm
- npm i nrm -g 全局安装 nrm
- nrm ls 查看镜像列表
- nrm use 镜像名称
- 初始化 react 项目 create-react-app
- npx create-react-app [项目名称]
- npm run start 启动项目
类组件形式
组件名称首字母必须大写
基本结构
import React, { Component } from 'react'
class ClassDemo extends React.Component{
constructor(){ //构造函数
super()
}
render(){
}
}
函数的定义
普通函数定义方式
- 使用的是普通函数,必须在 constructor 中通过 bind 修正 this 指向后才能使用
handleNum(){
let {num} = this.state
// num += 1
this.setState({ //唯一引发类组件数据响应式变化的方法
num:++num
})
}
箭头函数定义方式,不传参
handleNum = ()=>{
let {num} = this.state
this.setState({ //唯一引发类组件数据响应式变化的方法
num:++num
})
}
<button onClick={this.handleNum}>按钮</button>
调用方法函数并传参
handleNum = (n=1,ev)=>{
console.log(ev);
let {num} = this.state
num += n
this.setState({ //唯一引发类组件数据响应式变化的方法
num
})
}
传参时这样写()=>{this.xxx(n)} 不然会死循环
<button onClick={(ev)=>{this.handleNum(10,ev)}}>按钮</button>
列表渲染
{
this.state.joblist.map((item,index)=>{
return <JobItem jobname={item.jobname} salary={item.salary}/>
})
}
条件渲染
{
isShow
?
<input ref={this.myInput} type="text" />
:
''
}
setState 方法的回调
setState 方法是异步的
this.setState({
isShow:true
})
this.myInput.current.focus() //此处的DOM操作,会因为setState的异步特点,导致执行失败
//解决方案
this.setState({
isShow:true
},()=>{ //此处的回调函数,会等到isShow引发的DOM更新完成后,再执行
this.myInput.current.focus()
})
StyledComponents
使用
- npm i yarn -g 全局安装yarn
- yarn add styled-components 安装依赖
安装 vscode 插件 vscode-styled-components
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: #BF4F74;
`;
render(
<Title>
Hello World!
</Title>
);
生命周期
- 挂载阶段
- constructor
- render
- componentDidMount
- 更新阶段 (props、state 的变化都会触发更新)
- shouldComponentUpdate
- render
- componentDidUpdate
- 销毁阶段
- componentWillUnmount
- PureComponent (表现形式跟 Component 有差异)
组件通信方法汇总
父子、子父通信
- 父子通信
- 父级传数据
- 子级接收并使用
- 子父通信
- 父级传递函数
- 子级接收函数
- 子级触发父级提供的函数
- 父级函数中得到子级提供的数据
兄弟通信(状态提升)
为兄弟组件增加一个共同的父组件,进而实现通信
import React, { Component } from "react";
import CompA from "./ComA";
import CompB from "./CompB";
export default class UpperDemo extends Component {
constructor() {
super();
this.state = {
//状态提升
num: 111,
};
}
handleNum = () => {
let num = this.state.num + 1;
this.setState({
num,
});
};
render() {
return (
<div>
<CompA num={this.state.num} />
<CompB handleNum={this.handleNum} />
</div>
);
}
}
事件总线
- 定义总线对象
//事件总线,发布订阅模式【设计模式】
import { EventEmitter } from "events";
let bus = new EventEmitter();
// 进行通信信号的接收
export const $on = (callback) => {
bus.on("hello", callback); //callback是给用户接收信号后去触发的方法函数
};
// 进行通信信号的发送
export const $emit = (arg) => {
bus.emit("hello", arg); //arg是发射信号时携带的参数
};
- 在 C 组件中调用总线的信号监听方法
componentDidMount() {
$on((arg) => {
console.log("接收到了信号", arg);
this.setState({
msg: arg.msg,
});
});
}
- 在 D 组件中调用总线的信号发射方法
<button
onClick={() => {
$emit({
msg: "0707,收到请回答",
});
}}
>
发射信号
</button>
Context
理解上下文、作用及其特点
- Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。
- Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言。
- Context 主要应用场景在于很多不同层级的组件需要访问同样一些的数据。请谨慎使用,因为这会使得组件的复用性变差。
使用
- 创建上下文对象
import React, { Component } from "react";
// 1.创建上下文对象
const MyContext = React.createContext();
//如果浏览器安装过 react 的开发者工具,打开之后发现上述代码,都显示为 `Context.Provider` 和 `Context.Consumer`,不好区分加入 上下文对象的 `displayName`
ColorContext.displayName = "ColorContext"
- 传值
class App extends Component {
render() {
return (
<div>
{/* 在需要传值的地方,通过 上下文 对象 的 Provider 组件以及value属性配合传递数据 */}
<MyContext.Provider value="传家宝">
<First />
</MyContext.Provider>
</div>
);
}
}
- 后代获取数据
// 1. 如果后代组件是类组件 可以通过 类的静态属性 static contextType = 上下文对象 获取祖先组件的值,然后在jsx中 通过 this.context 取值即可
// class Third extends Component {
// static contextType = MyContext
// render () {
// return (
// <div>
// <h3>third!!</h3>
// <div>{ this.context }</div>
// </div>
// )
// }
// }
// 2. 如果不使用 静态属性,那么可以 通过 上下文对象.Consumer 来获取数据(在其内部图片通过函数返回jsx代码,函数的默认参数就是祖先组件传递的值)
class Third extends Component {
render() {
return (
<div>
<h3>third!!</h3>
<div>
<MyContext.Consumer>
{(value) => {
return <mark>{value}</mark>;
}}
</MyContext.Consumer>
</div>
</div>
);
}
}