大家好,欢迎来到IT知识分享网。
一、组件的优化
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(); 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(); 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) } }>< </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: '小米'}
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/148404.html