介绍react
facebook 构建用户界面的js库
组件开发
虚拟dom
单向数据流
jsx
react脚手架
安装
npm i create-react-app
创建react项目
create-react-app 项目名称
cd 项目目录
npm start
jsx语法
{}js表达
{/**/}注释
className 类名
数组可以有html标签 自动展开
style对象会自动展开
有且只有一个根节点
事件
onClick={函数}
事件传参
onClick={say.bind(this,参数)}
onClick={e=>{say(参数)}}
state状态
sateState(k:value)
表单的双向绑定
<input type="text" value={state.msg} onChange={(e)=>this.setState({msg:e.target.value})} /> <br />
dom引用
import React, { Component,createRef } from "react";
this.myref =createRef()
<button onClick={()=>alert(this.myref.current.value)}>获取dom元素</button>
条件渲染
三元运算
条件?真:反
条件&&内容
列表渲染
{ state.list.map((item, index) => <h4 key={index}>{ item}</h4>)}
基本格式
import React, { Component } from 'react';
class extends Component {
constructor(props) {
super(props);
}
state = { }
render() {
return ( );
}
}
export default ;
例子
// imrc 导入react 从react
// component 组件 createRef 创建引用
import React, { Component, createRef } from "react";
// ccc 创建一个class类 继承conponents组件
class App extends Component {
// 构造函数 props 是父组件传入的参数
constructor(props) {
// 调用父类的构造函数
super(props);
// 定义状态state 理解为vue中的data 存储数据
this.state = {
num: 1,
msg: "爱",
isLog: true,
flag: true,
list:["vue","jqury","react"]
};
// 创建一个dom引用
this.myref = createRef();
}
add = (n = 1) => {
this.setState({ num: this.state.num + n });
};
render() {
const state = this.state;
return (
<div>
<h1>列表渲染</h1>
{
state.list.map((item, index) => <h4 key={index}>{ item}</h4>)
}
<h1 onClick={() => this.setState({ isLog: !this.state.isLog })}>
条件渲染
</h1>
{this.state.isLog ? <p> 我是true</p> : <p> 我是false</p>}
{this.state.flag && <p>我是true 是我看中的人</p>}
<h1>获取dom元素</h1>
{/* 非受控表单 */}
<input type="text" ref={this.myref} />
{/* this.myref.current 代表input */}
<button onClick={() => alert(this.myref.current.value)}>
获取dom元素
</button>
<h1>表单双向绑定</h1>
<h3>{this.state.msg}</h3>
{/* 当表单发生变化时候 更新msg值 */}
{/* 受state控制的表单 称为受控表单 */}
{/*e.taret事件对象 表单input */}
<input
type="text"
value={state.msg}
onChange={(e) => this.setState({ msg: e.target.value })}
/>{" "}
<br />
<h1>事件</h1>
{/* 如果传入的函数名不带括号,默认调用会传入事件对象 */}
<button onClick={this.add}> 有参数 不带括号{this.state.num}</button>
<button onClick={() => this.add()}>{this.state.num}</button> <br />
<button onClick={this.add.bind(this, 1)}>{this.state.num}</button>{" "}
<br />
</div>
);
}
}
export default App;
// function 函数组件 视图组件 通常用于展示 (推荐使用)
// class 类组件 容器组件 存储数据 处理数据
react组件传参
父传子
父
import React, { Component } from "react";
import ChildB from "./components/ChildB";
import Modal from "./components/Modal";
class App extends Component {
state = {
// 控制是否弹框
visible: false,
};
// 设置visible为false 的方法
onclose = () => this.setState({ visible: false });
render() {
return (
<div>
{/* 单击按钮设置visible 为true */}
<button onClick={() => this.setState({ visible: true })}>
显示弹框
</button>
{/* 使用Modal弹框 传入属性 onclose 关闭弹框方法 visible控制弹框是否显示 */}
<Modal onclose={this.onclose} visible={this.state.visible}>
<p>弹框内容,插槽形式</p>
</Modal>
<h2>组件的插槽</h2>
<ChildB>
<p>掉头发</p>
<p>学前端</p>
</ChildB>
</div>
);
}
}
export default App;
子
import React, { Component } from "react";
class ChildB extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
子组件通过props.children 获取插槽内容
{this.props.children}
</div>
);
}
}
export default ChildB;
子传父
子
function ChildA(props) {
return (
<div>
<p>
{/* 父传子 props */}
ChildA 子组件{props.value}
</p>
{/* 子传父 通过props的回调函数实现 */}
<button onClick={()=>{props.setNum(100)}} >修改父组件的值为100</button>
</div>
)
}
export default ChildA
// 不写默认 传值
ChildA.defaultProps={value:1}
父
import ChildA from "./components/ChildA";
import React, { Component } from "react";
class App extends Component {
state = {
num: 5,
};
setNum = (v) => this.setState({ num: v });
render() {
return (
<div>
{/* 组件大写 组件可以被重复调用 首字母必须大写 */}
{/*把函数当作props传递给组件 */}
<ChildA
setNum={this.setNum}
value={this.state.num}></ChildA>
<ChildA></ChildA>
</div>
);
}
}
export default App;
react生命周期
挂载:
constructor 构造函数
static getDerivedStateFromProps(nextProps, PrevState)
state和props 更新时候会触发
render 渲染
componentDidMount () 组件已经挂载 (dom渲染完成)
更新
static getDerivedStateFromProps(nextProps, PrevState)
state和props 更新时候会触发
shouldComponentUpdate(nextProps, nextState)
组件是否更新 返回true更新反之不更新
render渲染函数
getSnapshotBeforeUpdate(prevProps, prevState)
更新前获取快照 返回值是cdu的第三个参数
componentDidUpdate(prevProps, prevState, snap)
组件已经更新 (dom渲染完毕
卸载
componentWillUnmount()
组件将要卸载
react优化方案
shouldComponentUpdate
shouldComponentUpdate(nextProps, nextState) {
if (this.props.value === nextProps.value) {
return false
} else {
return true
}
PureComponent
import React, { PureComponent } from "react";
class ChildC extends PureComponent {}
组件
函数组件
props
类组件
props state ref 生命周期
state,this 有限定组件的复用
组件推荐使用函数组件:
只有props 不依赖state,适应性更强,更解构
试图组件
Hooks
useState 使用 状态
导出:import { useState,} from "react";
使用 const [count, setCount] = useState(5);
count是数据名称 setcount是调用前面数据的方法 useState(这里填count的数据类型)
调用:num:{num}
更新: num<button onClick={()=>setNum(num+2)}>
useEffect
作用:模拟生命周期
模拟挂载完毕
useEffect(()=>{
模拟挂载完毕
},[])
useEffect(()=>{
模拟num挂载+更新
},[num])
useEffect(()=>{
模拟任意数据挂载加更新
})
模拟组件将要卸载
useEffect(()=>{
return ()=>{
模拟组件将要卸载
}
})
useRef
useMemo
useContext
useRenducer
路由
安装v6
npm i react-router-dom -S
路由配置
const baseRoutes=[
{path:' ',element:<home/>}
{path:' ',element:<home/>
children:[
"{path:' ',element:<Dash/>"
]
}
]
创建并返回路由
const element =useRoutes(baseRoutes)
return <>{element}</>
App.js包装
import { HashRoutes as Router} from " react-router-dome"
import RouterView from "./router"
<Router><RouterView></Router>
组件
HashRouter 哈希路由
所有的路由组件和方法都必须包裹在这个路由里面
Link 导航链接
Outlet 子路由容器
NavLink 导航链接 选中多个active
to =“ /about”
to={{pathname:"/about"}}
ues方法
useRoutes 创建路由
useParams 获取路由参数