reate的相关知识

一、组件的优化

1、componentWillUnmount

组件被销毁时,无法清空定时器,这样定时器会一直存储在内容中容易造成内存泄漏

父组件

​
​
class Index extends Component{
    constructor(){
        super()
​
        this.state={
            flag:true
        }
    }
​
​
    render() {
        return (
            <div>
             
                <button onClick={
                    ()=>{
                        this.setState({
                            flag:!this.state.flag
                        })
                    }
​
​
                }>切换home</button>
             
                { this.state.flag?<Home></Home>:"" }
​
            
            </div>
        );
    }
​
   
}
export default Index

子组件

class Home extends Component{
    constructor(){
        super()
​
        this.state={
            time:new Date().toLocaleTimeString()
        }
​
        this.timer=null
      
    }
    render() {
        return (
            <div>
                <h1>Home</h1>
                <h1>现在的时间:{this.state.time}</h1>
                
            </div>
        );
    }
​
    
    componentDidMount(){
        this.timer= setInterval(()=>{
            console.log(11111111111);
            this.setState({
                time:new Date().toLocaleTimeString()
            })
        },1000)
    }
​
    componentWillUnmount(){
        // 销毁定时器
​
        clearInterval( this.timer)
    }
    
}
export default Home

2、shouldComponentUpdate

当父组件发生变化时,都会重新触发子组件的render,浪费性能和资源。

shouldComponentUpdate(newprops,newstate){
    // console.log("子组件shouldComponentUpdate");
    // newprops  新传递过来的props 
    // newstate 新的state值
​
    // console.log(newprops);
​
    if(newprops.num ==this.props.num ){
        // 如果数据更新了,则重新渲染子组件
        return  false
    }else{
        // 如果数据没更新,则不更新子组件
        return true
    }
​
​
}

3、PureComponent

当父组件发生变化时,都会重新触发子组件的render,浪费性能和资源。可以使用PureComponent 替代Component 或者使用

import {PureComponent} from 'react'
​
class Home extends PureComponent{
    constructor(){
        super()
​
 
    }
    render() {
        console.log("子组件的render");
        return (
            <div>
                <h1>Home</h1>
               
                
            </div>
        );
    }
​
    componentDidUpdate(){
        console.log("子组件componentDidUpdate");
    }
​
    
}
export default Home

4、memo(在函数组件中使用)

当父组件发生变化时,都会重新触发子组件的render,浪费性能和资源。可以使用 React.memo(App) 这个高阶函数

import {memo} from "react"
​
​
function Home(){
​
    console.log("子组件的render");
    return (
        <div>
            <h1>Home</h1>
            
            
        </div>
    );
 
}
export default memo(Home)

5、Fragment

每一个组件都有一根标签div , Fragment是一个组件,不占位不显示,可以作为根标签

父组件

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <Home></Home>
​
</ul>

子组件

return (
​
    <Fragment>
        <li>4</li>
        <li>5</li>
        <li>6</li>
​
    </Fragment>
);

6、React.CreateContext() 隔代传值

Context 上下文环境

爷爷

<Provider value={obj}>
    <父组件></父组件>
</Provider>
import { Component,createContext } from 'react'
import Home from "./home.jsx"
​
//---------------------
export let {Consumer,Provider}=createContext()
​
class Index extends Component {
    constructor() {
        super()
​
​
        this.state={
            msg:"要好好学习",
            money:100
        }
​
    }
    render() {
        // console.log(createContext());
        // Consumer  顾客   接收着
        // Provider 售货员  提供者
​
       
        return (
            <div  className='box'>
                <h1>index</h1>
                <h1>{this.state.msg}</h1>
                <h1>${this.state.money}</h1>
​
​
                
                {/* ---------------------*/}
                <Provider value={ {...this.state }   }>
                      <Home></Home> 
                </Provider>
​
            </div>
        );
    }
​
​
}
export default Index

孙孙

<Consumer>
    {
        (e)=>{
​
            return JSON.stringify(e)
        }
    }
</Consumer>
import {Component} from 'react'
import "../assets/index.css"
​
//-------------------------
import {Consumer} from "./index.jsx"
​
​
class Home extends Component{
    render() {
​
​
        return (
            <div  className='box'>
                <h1>son</h1>
​
                <div>
                    
                    
                      {/* ---------------------*/}
                    <Consumer>
                        {
                            (e)=>{
                                // return JSON.stringify(e)
                                return "$"+e.money
                            }
                        }
                    </Consumer>
                </div>
            </div>
        );
    }
}
export default Home

7、componentDidCatch 错误边界

某个子组件发生了错误,或者要渲染的东西发生了错误,会导致整个页面渲染不到东西。我们希望谁出错了就不渲染谁,不要影响别的部分。

错误边界处理,应用于生产环境(不是让错误消失)

componentDidCatch(){
    // console.log(1111111);
    this.setState({
        isShow:false
    })
}
​
​
constructor() {
    super()
​
    this.state={
        isShow:true
    }
​
​
}
​
​
​
{ this.state.isShow?<Home></Home>:"" }

二、高阶组件

我们要创建一个高阶组件

HOC(Higherorder Component)是React的进阶使用方法,主要的目的是为了组件的复用。

HOC 本身并不是react的api,它只是一个方法,接收一个组件作为参数,返回一个增强组件的方法

子组件1

import {Component} from 'react'
import "../assets/index.css"
​
class Home extends Component{
    render() {
        return (
            <div >
                {/* <header>头部</header>
                <p>公共的部分 </p> */}
                <h1>home</h1>
                {/* <p>公共的部分 </p>
                <footer>尾部</footer> */}
            </div>
        );
    }
}
export default Home

子组件2

import {Component} from 'react'
​
class School extends Component{
    render() {
        return (
            <div >
                {/* <header>头部</header>
                <p>公共的部分 </p> */}
                <h1>School</h1>
                {/* <p>公共的部分 </p>
                <footer>尾部</footer> */}
            </div>
        );
    }
}
export default School

HOC抽离

​
​
function Public(Comp){
 
    return class Com extends Component{
​
​
        render(){
​
            return (
                <div className='box'>
                    <header>头部</header>
                    <p>公共的部分 </p>
                    <Comp></Comp>
                    <p>公共的部分 </p>
                    <footer>尾部</footer>
​
                </div>
            )
        }
​
    }
​
​
}
​

父组件

​
import Home from "./home.jsx"
import School from './school.jsx';
import Public from "./public.js"
​
let  Newhome=  Public(Home)
let  NewSchool=  Public(School)
​
​
class Index extends Component {
 
    render() {
  
        return (
            <div  className='box'>
                <h1>Index</h1>
             
                <Newhome></Newhome>
                <NewSchool></NewSchool>
              
            </div>
        );
    }
​
​
}
export default Index

三、路由

1、概念

通过不同的导航地址渲染不同的组件内容

2、下载路由

npm  i   react-router-dom

3、设置路由模式

HashRouter

import {HashRouter}  from "react-router-dom"
​
<HashRouter>
    <App />
</HashRouter>

BrowserRouter

index.js

import {BrowserRouter}  from "react-router-dom"
​
<BrowserRouter>
    <App />
</BrowserRouter>

4、路由视图出口 Routes

import {Routes} from "react-router-dom"
​
<Routes></Routes>

5、路由规则配置 Route

import {Routes,Route} from "react-router-dom"
​
<Routes>
    <Route path="路由"  element={  <组件 />  }></Route>
</Routes>
import {Routes,Route} from "react-router-dom"
import Index from "./pages/index"
import List from "./pages/list"
import Detail from "./pages/detail"
​
​
​
<Routes>
    <Route path="/index" element={ <Index></Index>   }></Route>
<Route path="/list" element={ <List></List>   }></Route>
<Route path="/detail" element={    <Detail></Detail>   }></Route>
</Routes>
​

6、重定向 Navigate

import {Routes,Route,Navigate} from  "react-router-dom"
<Routes>
    <Route path="*"  element={  <Navigate to="路由" />  }></Route>
</Routes>

import  {Routes,Route,Navigate} from "react-router-dom"
import Index from "./pages/index"
import List from "./pages/list"
import Detail from "./pages/detail"
​
​
​
<Routes>
    <Route path="/index" element={ <Index></Index>   }></Route>
    <Route path="/list" element={ <List></List>   }></Route>
    <Route path="/detail" element={    <Detail></Detail>   }></Route>
​
    {/* 不知道要捕获哪个路由,所以用一个 *  */}
    <Route path="*" element={  <Navigate to="/index" ></Navigate>   }></Route>
</Routes>

7、404

8、路由嵌套

主组件

import Index from "./pages/index"
import List from "./pages/list"
import Detail from "./pages/detail"
import  {Routes,Route,Navigate} from "react-router-dom"
​
​
<Routes>
    <Route path="/index/*" element={ <Index></Index>   }></Route>
    <Route path="/list" element={ <List></List>   }></Route>
    <Route path="/detail" element={    <Detail></Detail>   }></Route>
​
​
    {/* 不知道要捕获哪个路由,所以用一个 *  */}
    <Route path="*" element={  <Navigate to="/index" ></Navigate>   }></Route>
</Routes>

index组件

import Home from "../views/home"
import Cart from "../views/cart"
import Cate from "../views/cate"
import My from "../views/my"
import {Routes,Route,Navigate} from "react-router-dom"
​
​
​
<Routes>
    <Route  path='home' element={ <Home></Home>  }></Route>
    <Route  path='cart' element={ <Cart></Cart>  }></Route>
    <Route  path='cate' element={ <Cate></Cate>  }></Route>
    <Route  path='my' element={ <My></My>  }></Route>
​
    <Route  path='*' element={ <Navigate to="home"></Navigate>   }></Route>
​
</Routes>

9、路由导航 Link 组件 和NavLink组件

import {Link,NavLink} from "react-router-dom"
​
​
<div className='navlist'>
    {/* <Link to="home">商城</Link>
                        <Link to="cate">分类</Link>
                        <Link to="cart">购物车</Link>
                        <Link to="my">个人中心</Link> */}
​
    {/* 可以解析 .active 的样式 */}
​
    <NavLink to="home">商城</NavLink>
    <NavLink to="cate">分类</NavLink>
    <NavLink to="cart">购物车</NavLink>
    <NavLink to="my">个人中心</NavLink>
</div>

10、编程式导航 useNavigate()

只能在函数组件中使用

语法:

 useNavigate()("跳转的路由")  // push模式
​
 useNavigate()("跳转的路由",{replace:true}) //  replace模式
​
 useNavigate()(-1)  // 回退 
​
import  {useNavigate} from "react-router-dom"
​
​
function Home(){
​
    // useNavigate 只能在函数里面调用
    console.log(useNavigate());
    let nav=useNavigate()
​
    
    return (
        <div className="home">
​
            <ul>
                
               <li  onClick={
                        ()=>{
                            nav("/detail")
                            // nav("/detail",{replace:true})
                        }
                    }>跳转到详情</li>
                
            </ul>
        </div>
    );
}
import {useNavigate} from "react-router-dom"
​
​
function Detail(){
    let  nav=useNavigate()
​
    return (
        <div>
            <header> <span onClick={
                ()=>{
                    nav(-1)  
                }
​
            }>&lt; </span> 头部</header>
            <h1>Detail</h1>
        </div>
    );
}
​
export default Detail

11、路由传参

接惨只能在函数组件中使用

11.1 查询字符串

  • 传参

<ul>
    {
        list.map(item=>{
            return <li key={item.id}>
​
                {/* 查询字符串的形式传参 */}
​
                {/* <Link to={"/detail?id="+item.id }>{item.goodsname}</Link> */}
                <Link to={`/detail?id=${item.id}` }>{item.goodsname}</Link>
            </li>
        }) 
    }
</ul>

  • 接参

useLocation()

import {useLocation} from "react-router-dom"
​
​
function  getsearch(userSearch){
​
     let {search}=userSearch 
     let  querystirng=search.substring(1)
     let arr=querystirng.split("&")
 
     let obj={}
     arr.forEach(item=>{
         let arr1=  item.split("=")   
         obj[arr1[0]]=decodeURI(arr1[1])
     })
    return  obj
}
​
​
​
​
​
function Detail(){
​
    let query=getsearch( useLocation() )
    // console.log(query); //{id: '2', goodsname: '小米'}
​
​
    return (
        <div>
            <h1>Detail</h1>
        </div>
    );
}
export default Detail

usSearchParams()

// console.log( useSearchParams());//[URLSearchParams, ƒ]
​
let [URLSearchParams]=useSearchParams()
console.log(URLSearchParams);//URLSearchParams {}
​
// console.log( URLSearchParams.get("id")  );
// console.log( URLSearchParams.get("goodsname")  );

11.2 state

传参

<ul>
    {
        list.map(item=>{
            return <li key={item.id}>
                <Link 
                    
                    to={`/detail`}  
                    state={ {id:item.id,goodsname:item.goodsname} }
                    
                >{item.goodsname}</Link>
            </li>
        }) 
    }
</ul>

useLocation()

 console.log(useLocation().state);//{id: 2, goodsname: '小米'}

11.3 动态路由传参

路由配置:

  <Routes>
​
    <Route path="/detail/:id/:goodsname" element={    <Detail></Detail>   }></Route>
​
</Routes>

路由跳转

​
​
<ul>
    {
        list.map(item=>{
            return <li key={item.id}>
​
                <Link to={`/detail/${item.id}/${item.goodsname}`}  >{item.goodsname}</Link>
                
            </li>
        }) 
    }
</ul>

接参:useParams()

import {useParams} from "react-router-dom"
​
console.log(useParams());//{id: '2', goodsname: '小米'}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值