1 创建react元素
参数:元素名称 元素属性 元素的子节点
const title=React.createElement('h1','','hello')
2 渲染react元素
参数:要渲染的react元素 渲染的位置
ReactDom.render(title,document.getElementById('root'))
3 react脚手架的使用
npx create-react-app my-app
启动:npm start
4 使用函数创建组件
注:首字母大写
function Hello(){
return (
<div>111</div>
)
}
ReactDOM.render(<Hello/>,document.getElementById('root'))
5 使用类创建组件
class Hello extends React.Component{
render(){
return (
<div>1111111111</div>
)
}
}
6 事件绑定this指向
(1)使用箭头函数
onClick={()=>this.btnClick()}
(2)函数使用箭头函数形式
7 多表单元素优化
对于select、checkbox、input、textarea动态绑定数据变化
handleChange=e=>{
const target=e.target
const value=target.type==='checkbox'?target.checked:target.value
const name=target.name
this.setState({
[name]:value
})
}
8 获取非受控组件的值
constructor(){
super()
this.txtRef=React.createRef()
}
//获取值使用this.txtRef.current.value
<div ref={this.txtRef} />
9 组件之间的通讯
(1)父组件传递给子组件
const son=name=>{
return <div>{name}</div>
}
const father=()=>{
return <son name=props></son>
}
(2)子组件传递数据给父组件
class Parent extends React.Component{
state:{
myMsg:''
}
getMes=(data)=>{
console.log(data)
this.setState({
myMsg:data
})
}
render(){
return (
<div>
<Child msg={this.getMes} />
</div>
)
}
}
class Son extends React.Component{
state:{
myMsg:''
}
handleClick=()=>{
this.props.msg(this.state.myMsg)
}
render(){
return (
<div>
<button OnClick={this.handleClick} />
</div>
)
}
}
(3)兄弟组件通讯:将共享状态放于公共父组件中
(4)context通讯
const {Provider,Consumer} =React.createContext()
<Provider value='111'></Provider>
<Consumer>
{
data=>{
<span>{data}</span>
}
}
</Consumer>
注:props包含一个children属性
props校验:
组件名.propTypes={
value:propTypes.array
}
添加props的默认值:组件名.defaultProps
10 React的生命周期
组件创建时生命周期的执行顺序:constructor()->render()->componentDidMount()
触发时机 | 作用 | |
---|---|---|
constructor | 创建组件时执行 | 初始化state、为事件处理程序绑定this |
render | 每次组件渲染都会触发 | 渲染UI(但是不能调用setState) |
componentDisMount | 组件挂载后 | 发送网络请求、DOM操作 |
卸载生命周期钩子函数:componentWillUnmount
11 组件复用(高阶组件)
步骤:
1、创建函数,名称以with开头
2、指定函数参数,参数以大写字母开头,作为要渲染的组件
3、在函数内部创建一个类组件,提供复用的逻辑代码,并返回
4、在该组件中,渲染参数组件,同时将状态通过prop传递给参数组件
5、调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
使用高阶组件复用时会得到相同的名称,通过设置displayName区分不同组件
function withMouse(WrappedComponent){
class Mouse extends React.Component{
state={
x:0,
y:0
}
handleMouseMove=e=>{
this.setState({
x:e.clientX,
y:e.clientY
})
}
componentDidMount(){
window.addEventListener('mouseover',this.handleMouseMove)
}
componentWillUnmount(){
window.removeEventListener('mouseover',this.handleMouseMove)
}
render(){
return <WrappedComponent {...this.state}{...this.props}></WrappedComponent>
}
}
return Mouse
}
const Position=props=>(
<p>
鼠标当前位置:(x:{props.x},y:{props.y})
</p>
)
const MousePosition=withMouse(Position)
ReactDOM.render(<MousePosition></MousePosition>,document.getElementById('root'))
12 组件性能优化
(1)减轻state
(2)避免不必要的重新渲染:shouldComponentUpdate(nextProps,nextState)
使用this.state获取更新前的状态。使用nextstate获取更新后的状态
(3)纯组件
13 React-router
(1)模糊匹配模式
//只要pathname以path开头,就能匹配成功
<Link to="/login/a"/>
<<Route path="/login">
(2)精确匹配
给Route组件添加exact属性,只有当path和pathname完全匹配时才会成功
14 React中的事件绑定与原生事件绑定有什么区别
react中事件绑定采用事件代理,并没有绑定在具体的元素上
15 useState
注意:只能出现在函数组件中,不能嵌套在if/for/其他函数中
const [count,setCount]=useState(0)
const[flag,setFlag]=useState(true)
const[list,setList]=useState([])
const[name,setNAme]=useState('')
16 useEffect
默认状态时,每次数据修改就会执行
//依赖项为空数组时,仅在组件初始化时执行一次
useEffect(()=>{
document.title=count
},[])
//依赖特定项,初始化时执行一次,依赖项变化时再次执行
useEffect(()=>{
document.title=count
},[count])
17 useRef(获取组件实例)
const textRef=useRef(null)
textRef.current获取当前组件
18 useContext(在hooks下使用context)
查找机制:先去最近的provider中找,回去找createContext传过来的默认参数
const Context=createContext()
父组件中使用Context.Provider包裹
子组件中使用useContext()获取值
19 React路由
BrowserRouter声明当前要用一个非hash模式的路由
HashRouter声明使用一个hash模式的路由
path指定匹配的路径地址,element属性指定要渲染的组件
<Routes>
<Route path='' element={<组件>}>
</Routes>
使用useNavigate进行跳转
const navigate=useNavigate()
function go(){
navigate('/about',{replace:true}) //跳转时不想加历史记录,将replace设为true
}
跳转时携带参数
(1)使用useSearchParams传参
navigate('/about?id=1001',{replace:true})
const [params]=useSearchParams()
const id=params.get['id']
(2)使用useParams传参
<Route path='/about/:id' element={<About/>}></Route>
navigate('/about/1001',{replace:true})
const params=useSearchParams()
const id=params.id
路由嵌套
<Route path='/' element={<Home/>}>
<Route path='board' element={<Board/>}></Route>
</Route>
//在home组件中添加出口
<Outlet></Outlet>
//默认渲染二级路由
<Route path='/' element={<Home/>}>
<Route index element={<Board/>}></Route>
</Route>
404路由设置
在各级路由的最后添加path为*的路由设置
20 Mobx(集中状态管理工具)
//实现点击自加
import {makeAutoObservable} from 'mobx'
class counter{
count=0
constructor(){
makeAutoObservable(this)
}
addCount=()=>{
this.count++
}
}
const store=new counter()
export {store}
import {store} from './counter'
import {observer} from 'mobx-react-lite'
function App(){
return (
<div>
<span>{store.count}</span>
<button onClick={store.addCount}>click</button>
</div>
)
}
export default observer(App)
实现计算属性:在方法前面加上get
mobx的模块化:
import {CounterStore} from './counter.Store'
import {ListStore} from './list.Store'
import React from 'react'
class RootStore{
constructor(){
this.countstore=new CounterStore()
this.liststore=new ListStore()
}
}
const rootStore=new RootStore()
const context=React.createContext(rootStore)
const useStore=()=>React.useContext(context)
export {useStore}