react学习备忘


react学习备忘


提示:以下是本篇文章正文内容,下面案例可供参考

1. 创建react应用

  1. 全局安装,npm install -g create-react-app
  2. 在项目目录中,运行create-react-app 项目名
  3. 进行项目目录
  4. 启动项目 npm start

2. 定义组件

2.1 函数式组件

import React from 'react'
export default function Page() {
    
    
	return <div>我是函数式组件</div>
}

2.2 类式组件

import React from "react"
class Page3 extends React.Component {
    
    
  render() {
    
    
    return <div>page3</div>
  }
}
export default Page3

3. state

3.1 类式组件中的应用

import React from "react"
class Page3 extends React.Component {
    
    
  state = {
    
     name: '张三' }

  changeName = ()=> {
    
    
    this.setState({
    
     name: '李四' })
  }
  render() {
    
    
    return <div onClick={
    
     this.changeName }>姓名为{
    
     this.state.name }</div>
  }
}
export default Page3
// setState在同步代码中,是异步执行,在异步代码中,是同步执行
this.setState({
    
    xxxx: dddd}, ()=> {
    
    
	// setSate执行完,并更新完页面(render函数执行完后),执行回调函数
})

3.2 useState

import React, {
    
     useState } from 'react'

export default function Page4() {
    
    
  const [ name, setName ]  = useState('张三')

  const changeName = () =>{
    
    
    setName('李四')
  }
  return (
    <div onClick={
    
     changeName }>姓名为:{
    
     name }</div>
  )
}

4. props

父组件中

		const data = {
    
    {
    
     id: 1, name: '张三', age: 18 }}
		<Page3 {
    
    ...data}></Page3>
        <Page4 id={
    
    data.id} name={
    
    data.name} age={
    
    data.age}></Page4>

4.1 类式组件

import React from "react"
import PropTypes from 'prop-types'
class Page3 extends React.Component {
    
    
	static propTypes = {
    
    
	    name: PropTypes.string.isRequired,
	    sex:PropTypes.string,
	    age:PropTypes.number
	  }
	  static defaultProps = {
    
    
	    age: 118,
	    sex: '男'
	  }
  render() {
    
    
    return (
      <div>
        <div>编号:{
    
     this.props.id }</div>
        <div>姓名:{
    
     this.props.name }</div>
        <div>年龄:{
    
     this.props.age }</div>
      </div>
    )
  }
}
export default Page3

4.2 函数式组件

import React from 'react'
import PropTypes from 'prop-types'

export default function Page4(props) {
    
    
  return (
    <div>
      <div>编号:{
    
     props.id }</div>
      <div>姓名:{
    
     props.name }</div>
      <div>年龄:{
    
     props.age }</div>
    </div>
  )
}
Page4.proptypes = {
    
    
	id: PropTypes.string.required,
	name: PropTypes.string,
	age: PropTypes.number
}
Page4.defaultProps = {
    
    
	age: 18
}

子组件给父组件传参

通过父组件给子组件传递自定义方法,在子组件中调用,并传递参数,此时,父组件的形参中就能接收到子组件传递来的参数

// 父组件
import React from 'react'
import Child from 'xxxxxx'
class Father extends React.Component {
    
    
	render() {
    
    
		return {
    
    
			<Child add={
    
     this.add }></Child>
		}
	}
	add = (val)=> {
    
    
		// 子组件调用用,val就是子组件传递来的参数
	}
}

// 子组件
import React from 'react'
class Child extends React.Component {
    
    
	render() {
    
    
		return( xxxxxx )
	}
	componentDidMount() {
    
    
		// 调用父组件传递过来的自定义方法,给父组件传参
		this.props.add('123456789')
	}
}

5. ref

5.1 类式组件

import React from "react"
class Page3 extends React.Component {
    
    
  div2 = React.createRef()
  render() {
    
    
    return (
      <div>
        <div ref={
    
    c=> this.div1 = c}>回调函数类型的ref</div>
        <div ref={
    
    this.div2}>createRef类型的ref</div>
      </div>
    )
  }
  componentDidMount() {
    
    
    console.log(this.div1.innerHTML)
    console.log(this.div2.current.innerHTML)
  }
}
export default Page3

5.2 函数式组件

import React, {
    
     useRef } from 'react'

export default function Page4(props) {
    
    
  const divRef = useRef()
  console.log(divRef.current.innerHTML)
  return (
    <div ref={
    
     divRef }>我是一段文本</div>
  )
}

6. 生命周期

6.1 类式组件

  1. 初始化阶段
    • componentWillMount ---------------------已移除,不推荐使用
    • render
    • componentDidMount ---------------------dom渲染完执行,经常使用
  2. 运行阶段
    • componentWillReceiveProps ------------已移除,不推荐使用,父组件修改属性时触发,接收一个参数,nextProps
    • shouldComponentUpdate ----------------返回false,不更新组件,接收两个参数,一个是新的nextProps,一个新的nextState,可以用来做性能优化,如果接收到的props不再变化,就不要render子组件。让其返回一个false。(也可以用PureComponent,定义类是,不要继承React.Component,改为继承React.PureComponent,就可以达到相同的效果)
    • componentWillUpdate --------------------已移除,不推荐使用
    • render
    • componentDidUpdate---------------------接收两个参数,一个是之前的preProps,一个是之前的preState
  3. 销毁阶段
    • componentWillUnmount------------------组件将要销毁时调用
  • 新生命周期
    *
    • getSnapshotBeforeUpdate -------------- render后,componentDidUpdate前执行,他要return一个值,这个值作为componentDidUpdate的第三个参数,可以被componentDidUpdate接收
import React from "react"
class Page3 extends React.Component {
    
    
  componentWillMount() {
    
     xxxxxxxxxxxx }
  render() {
    
    
    console.log('render, 组件初始化或者组件被更新时调用')
    return (
      <div>xxxxx</div>
    )
  }
  componentDidMount() {
    
    
    console.log('componentDidMount, 组件挂载页面完成后调用')
  }
  shouldComponentUpdate(nextProps, nextState) {
    
     
    if(JSON.stringify(this.state) === JSON.stringify(nextState)) {
    
    
      return false
    }
    return true
   }
  componentDidUpdate(preProps. preStates) {
    
    
  	// 接收两个参数,一个是之前的prop,一个是之前的state
    console.log('componentDidUpdate,组件被更新后调用')
  }
  componentWillUnmount() {
    
    
    console.log('componentWillUnmount,组件将要被销毁时调用')
  }
}
export default Page3

7. 列表循环 && 插槽

7.1 列表循环

// 类式组件中应用
import React from "react"
class Page3 extends React.Component {
    
    
  state = {
    
    
    list: [
      {
    
     id:1, name: 'zs', age: 18 },
      {
    
     id:2, name: 'ls', age: 19 },
      {
    
     id:3, name: 'ww', age: 20 },
    ]
  }
  render() {
    
    
    return (
      <>
        {
    
    this.state.list.map(item=> {
    
    
          return <div key={
    
     item.id }>姓名:{
    
     item.name },年龄{
    
     item.age }</div>
        })}
      </>
    )
  }
}
export default Page3




// 函数式组件应用
import React, {
    
     useState } from 'react'

export default function Page4(props) {
    
    
  const [list, setList] = useState([
      {
    
     id:1, name: 'zs', age: 18 },
      {
    
     id:2, name: 'ls', age: 19 },
      {
    
     id:3, name: 'ww', age: 20 }
  ])
  return (
      <>
        {
    
    list.map(item=> {
    
    
          return <div key={
    
     item.id }>姓名:{
    
     item.name },年龄{
    
     item.age }</div>
        })}
      </>
  )
}

7.2 插槽

  • 父组件中,直接在子组件的标签体内写要在插槽放入的内容
  • 子组件中,通过this.props.children来放入查询内容
// 父组件中
import React from 'react';
import Page3 from './view/page3'
class App extends React.Component {
    
    
  render() {
    
    
    return (
      <div>
        <Page3>
          <div>我是插槽内容1</div>
          <div>我是插槽内容2</div>
          <div>我是插槽内容3</div>
        </Page3>
      </div>
    )
  }
}

export default App;


// 子组件中
import React from "react"
class Page3 extends React.Component {
    
    
  render() {
    
    
    return (
      <>
        <h2>我是子组件</h2>
        <div>{
    
     this.props.children }</div>
      </>
    )
  }
}
export default Page3

8. React Hooks

8.1 useState()

上方state中已经总结,不做重复总结
 

8.2 useEffect(), 副作用函数

useEffect(()=> {
    
    
	// xxxxxx
}, [])
  1. 接收两个参数,第一个参数是一个函数,第二个参数是一个数组

  2. 如果第二个参数是一个空数组,函数只会执行一次。此时类似于componentDidMount

  3. 如果第二个参数放入某个数据(从useState中解构出来),则该数据初始化和改变时,都会调用该函数。

    • 类似于componentDidMountcomponentDidUpdate 两个生命周期函数。
    • 通过对比发现,函数式组件中,如果依赖更新了,useEffect的回调函数就会执行
    • 但是,类式组件中,只要调用setState,无论数据是否相对于之前有更新,componentDidUpdate就会被执行。因此,在类式组件中,会用shouldComponentUpdate去判断新旧状态是否改变,以此来判断是否向下继续执行更新流程,或者使用PureComponent
  4. 模拟componentWillUnmount

    useEffect(()=> {
          
          
       var timer = setInterval(()=> {
          
          
         console.log(111111)
       }, 500)
       return () => {
          
          
         clearInterval(timer)
       }
     }, [])
    

8.3 useCallback(), 记忆函数

 
当父组件更新或者自身state更新时,函数式组件创建时的函数,会被整体重新执行,useSate(),就是一个记忆函数,保证创建的数据,只有在第一次执行的时候是将值赋给数据,后续更新后,不会重新执行。而,useCallback(),就是将自定义函数进行记忆,保证后续更新时,自定义函数不会重新创建。

const 自定义函数名 = useCallback(()=> {
    
    
	// xxxxxxxxx
}, [依赖])

8.4 useMemo()

 
可以当做计算属性使用,实例代码如下:

import React, {
    
     useMemo, useState } from 'react'

export default function Page4(props) {
    
    
  const [num ,setNum] = useState(123)
  const doubleNum = useMemo(()=> {
    
    
    return num * 2
  }, [num])
  return (
      <>
        <div>{
    
     num }</div>
        <button onClick={
    
    ()=> {
    
    
          setNum(num + 1)
        }}>num+1</button>
        <div>{
    
     doubleNum }</div>
      </>
  )
} 

8.5 useRef()

import React, {
    
     useRef } from 'react'
export default function Page4(props) {
    
    
  const myInput = useRef()
  return (
      <>
        <input type="text" ref={
    
     myInput }/>
      </>
  )
} 

9. css,sass模块化

9.1 css模块化

     1. 给css文件名中加上modules
     2. 引入css时,不在使用import '....' 这种方式。  通过 import xxx from '....' 进行引入
     3. 使用时,不在使用 `<div classNanme="main"></div>`, 而是通过 <div className={ xxx.main }></div>
  • 定义样式时:global(.aaaa){ text-algin:center },表名这个样式时全局的,不会加上随机后缀

9.2 使用sass

一. 在react可以通过安装sass后,直接进行使用,如果使用less,还要对webpack进行配置,较麻烦。
1. 执行 npm install sass 后即可使用sass

二. sass和scss的区别。
1. sass和scss其实是一样的css预处理语言,SCSS 是 Sass 3 引入新的语法,其后缀名是分别为 .sass和.scss两种。
2. SASS版本3.0之前的后缀名为.sass,而版本3.0之后的后缀名.scss。
3. 后缀名为.sass的文件编译后没有{}, 而后缀名.scss编译的文件有{}。

三. 最佳搭配
sass + 后缀名为.scss

*/

10. 路由

10.1 基于v5版本

10.1.1 基本使用

  1. 安装react-router-dom插件 npm i react-router-dom

  2. 导航区

    <Link to='/xxxx'>跳转至Demo</Link> 
    
  3. 展示区定义路由规则

    • Route 标签外面用 Swich标签进行包裹,这样,找到对应的路由后,就不会继续查找
    <Switch>
    	<Route path="/xxxxx" component={Demo}></Route>
     </Switch>
    
  4. 的最外面包裹BrowserRouter或者 HashRouter

    <BrowserRouter>
    	<App/>
    </BrowserRouter>
    
  • 注意

<Link> <Route> <BrowserRouter>使用时要在react-router-dom进行引入

import {
    
     Link, Route, BrowserRouter } from 'react-router-dom'

10.1.2 NavLink

NavLink标签可以为选择的NavLink标签自动添加一个active的样式类,我们可以以此来控制NavLink标签被选中后的样子。我们也可以通过activeclassname标签来自定义选中后的样式类

// *******************App.js********************
import React from 'react';
import Page1 from './view/page1'
import Page2 from './view/page2'
import './App.css'
import {
    
     NavLink, Route, Routes} from 'react-router-dom'
class App extends React.Component {
    
    
  render() {
    
    
    return (
      <div style={
    
    {
    
     display: 'flex' }}>
        <div className='nav'>
        {
    
    /*  6版本中 activeClassName要写成 activeclassname    */}
          <NavLink to={
    
    '/page1'} activeClassName="cusActive">page1</NavLink>
          <NavLink to={
    
    '/page2'} activeClassName="cusActive">page2</NavLink>
        </div>
        <div>
          <Routes>
            <Route element={
    
    <Page1/>} path="/page1"></Route>
            <Route element={
    
    <Page2/>} path="/page2"></Route>
          </Routes>
          
        </div>
      </div>
    )
  }
}

export default App;
/* ********************App.css******************** */
.nav a {
    
    
  display: block;
  width: 100px;
  line-height: 40px;
  text-align: center;
  border: 1px solid #ccc;
  color: black;
}
.active {
    
    
  background-color: yellow;
  color: #fff;
}

10.1.3 Redirect 重定向(在v6版本已移除)

指定如果没有可匹配的路由,将页面指向的地址

import React from 'react'
import {
    
     Redirect, Switch, Route } from 'react-router-dom'
import NotFund from './view/notFund'

class App extends React.Component {
    
    
	render() {
    
    
		return {
    
    
			<Switch>
				<Route path="/page1" component={
    
    page1}></Route>
				<Route path="/page2" component={
    
    page2}></Route>
				<Redirect to="/page1"></Redirect>
				// 如果输入不存在的地址,展示404页面,可以按照以下方案
				<Redirect from="/" to="/page1" exact></Redirect>
				<Route element={
    
    <NotFund/>}></Route>
			</Switch>
		}
	}
}

10.1.4 嵌套路由

  • 一级路由不要严格匹配,不能加exact
  • 二级路由的地址规则,要加上一级路由的规则<Route path={'/page1/Details'} component={Details}></Route>
import React from 'react'
import {
    
     Link, Redirect, Route, Switch } from 'react-router-dom'
import Details from './details'
import News from './news'

export default function Page1() {
    
    
  return (
    <div>
      <div>page1</div>
      <p>
      <Link to={
    
    '/page1/Details'}>详情</Link>
      </p>
      <p>
      <Link to={
    
    '/page1/News'}>新闻</Link>
      </p>
      <div>
        <Switch>
          <Route path={
    
    '/page1/Details'} component={
    
    Details}></Route>
          <Route path={
    
    '/page1/News'} component={
    
    News}></Route>
          <Redirect from='/page1' to={
    
    '/page1/Details'}></Redirect>
        </Switch>
      </div>
    </div>
  )
}

10.1.5 路由传参-params参数

import React from 'react'
import {
    
     Redirect, Switch, Route, Link } from 'react-router-dom'

class App extends React.Component {
    
    
	render() {
    
    
		return {
    
    
			// 声明向路由组件传递params参数
			<Link to=`/page1/${
      
      1}`></Link>
			<Link to=`/page2/${
      
      2}`></Link>

			// 声明接收parmas参数
			<Switch>
				<Route path="/page1/:id" component={
    
    page1}></Route>
				<Route path="/page2/:id" component={
    
    page2}></Route>
				<Redirect to=`/page1/${
      
      3}`></Redirect>
			</Switch>
			// 在组件内通过this.props.match.params获取参数
		}
	}
}

10.1.6 路由传参-search参数

import React from 'react'
import {
    
     Redirect, Switch, Route, Link } from 'react-router-dom'

class App extends React.Component {
    
    
	render() {
    
    
		return {
    
    
			// 声明向路由组件传递search参数
			<Link to=`/page1/?id=${
      
      1}&title=${
      
      obj.title}`></Link>
			<Link to=`/page2/?id=${
      
      2}&title=${
      
      obj.title}`></Link>

			// search参数不需要声明接收
			<Switch>
				<Route path="/page1" component={
    
    page1}></Route>
				<Route path="/page2" component={
    
    page2}></Route>
				<Redirect to=`/page1`></Redirect>
			</Switch>
			// 在组件内通过this.props.loaction.search获取参数
			// 但是需要引入qs进行转码
			// import qs from 'querystring'
			// qs.parse(this.props.loaction.search.slice(1))
		}
	}
}

10.1.7 路由传参-state参数

params参数和search参数会将参数在地址栏中进行暴露,而state参数不会在地址栏进行暴露

import React from 'react'
import {
    
     Redirect, Switch, Route, Link } from 'react-router-dom'

class App extends React.Component {
    
    
	render() {
    
    
		return {
    
    
			// 声明向路由组件传递state参数
			<Link to={
    
    {
    
     pathname: '/page1', state: {
    
    id: 1, title: '哈哈哈'} }}></Link>
			<Link to={
    
    {
    
     pathname: '/page2', state: {
    
    id: 2, title: '嘿嘿嘿'} }}></Link>

			// state参数不需要声明接收
			<Switch>
				<Route path="/page1" component={
    
    page1}></Route>
				<Route path="/page2" component={
    
    page2}></Route>
				<Redirect to=`/page1`></Redirect>
			</Switch>
			// 在组件内通过this.props.loaction.state获取参数
		}
	}
}

export default App

10.1.8 编程式路由

import React from 'react'
import {
    
     Redirect, Switch, Route, Link } from 'react-router-dom'

class App extends React.Component {
    
    
	render() {
    
    
		return {
    
    
			<button onClick="()=>{this.replaceTo()}">replace跳转</button>
			<button onClick="()=>{this.pushTo()}">rpush跳转</button>
			<Switch>
				<Route path="/page1" component={
    
    page1}></Route>
				<Route path="/page2" component={
    
    page2}></Route>
				<Redirect to=`/page1`></Redirect>
			</Switch>
		}
	}
	replaceTo = () => {
    
    
		// params传参
		this.props.history.replace('/page1/1/哈哈哈')
		// search传参
		this.props.history.replace('/page1?id=1&title=哈哈哈')
		// state传参
		this.props.history.replace('/page1',{
    
    id: 1, title: '哈哈哈'})
	}
	pushTo = () => {
    
    
		this.props.history.push('/page2')
	}
}

export default App

  • 如果是函数式组件,可以通过import { useHistory } from ‘react-router-dom’,引入hooks,
  • 实例化history对象,const history = useHistory()
  • history.push() 或者history.replace()

10.1.9 withRouter

非路由组件的this.props上面没有history属性,因此如果要在非路由组件上使用编程式导航,要通过withRouter

import React from 'react'
import {
    
     withRouter } from 'react-router-dom'

class App extends React.Component {
    
    }

export default withRouter(App)

10.1.10 路由拦截

  • 通过render方法配置的组件,其身上的props是没有router的相关属性的。要通过手动传递props的方式进行传递
  • 通过component配置的组件,相当于,这个组件是Router的子组件,因此他的身上的prosprouter相关的属性和方法
import React from 'react'
import {
    
     Switch, Route }  from 'react-router-dom'
// import  各个组件
export default function App() {
    
    
	return (
		<div>
			<button>page1</button>
			<button>page2</button>
			<div>
				<Switch>
					<Route to='/page1' render={
    
    ()=> <Page1 /> }></Route>
					<Route to='/page2' render={
    
    (props)=>{
    
    
						判断逻辑? <Page2 {
    
    ...props} > : <Redirect to={
    
    '/login'}>
					}}></Route>
					<Route to='/login' render={
    
    ()=> <Login/> }></Route>
				</Switch>
			</div>
		</div>
		
		
	)

}

10.2 基于v6.版本

10.2.1 基本使用

  1. 安装react-router-dom插件 npm i react-router-dom

  2. 导航区

    <Link to='/xxxx'>跳转至Demo</Link>
    
  3. 展示区定义路由规则

    • Route外层用Routes进行包裹
    • comonent属性改为element属性
    <Routes>
    	<Route path="/xxxxx" element={<Demo/>}></Route>
    </Routes>
    
  4. 的最外面包裹BrowserRouter或者 HashRouter

    <BrowserRouter>
    	<App/>
    </BrowserRouter>
    
  • 注意

<Link> <Route> <BrowserRouter>使用时要在react-router-dom进行引入

import {
    
     Link, Route, BrowserRouter, Routes } from 'react-router-dom'

10.2.2 重定向

通过Navigate组件实现重定向

<Route path="/" element={<Navigate to="/page1">}/>
import React from 'react';
import NotFund from './view/notFund';
import Page1 from './view/page1'
import Page2 from './view/page2'
import {
    
     Link , Route, Routes, Navigate} from 'react-router-dom'
class App extends React.Component {
    
    
  render() {
    
    
    return (
      <div style={
    
    {
    
     display: 'flex' }}>
        <div className='nav'>
          <Link to='/page1'>page1</NavLink>
          <Link to='/page2'>page2</NavLink>
        </div>
        <div>
          <Routes>
            <Route element={
    
    <Page1/>} path="/page1"></Route>
            <Route element={
    
    <Page2/>} path="/page2"></Route>
            <Route path='/' element={
    
    <Navigate to="/page1"/>}></Route>
            <Route path='*' element={
    
    <NotFund/>}></Route>
          </Routes>
          
        </div>
      </div>
    )
  }
}

export default App;

10.2.3 useRoutes创建路由表及路由嵌套

  • 创建路由表
import {
    
     Navigate } from 'react-router-dom'
import Page1 from './view/page1'
import Details from './view/page1/Details .jsx'
import News './view/page1/News .jsx'
import Page2 from './view/page2'

export default [
	{
    
    
		path: '/page1',
		element: <page1/>,
		children: [
			{
    
    
				path: 'details/:paramsId/:name',
				element: <Details />,
			},
			{
    
    
				path: 'news',
				element: <News />,
			}
		]
	},
	{
    
    
		path: '/page2',
		element: <page2/>
	},
	{
    
    
		path: '/',
		element: <Navigate to='/page1'/>
	}
]
  • 在组件中使用
// 在App组件中使用
import React from "react"
import {
    
     useRoutes, Link} from 'react-router-dom'
import routes from '../routes'

export default function App() {
    
    
	const element = useRoutes(routes)
	return (
		// 注册路由
		<Link to='/page1'>page1页面<Link/>
		<Link to='/page2'>page2页面<Link/>
		<div>
			{
    
     element }	
		</div>
		
	)
}

// 在page1页面中使用
import React from "react"
import {
    
     Link, Outlet, useParams, useSearchParmas } from 'react-router-dom'

export default function Page1() {
    
    
	const {
    
     id, name } = useParams()
	const 
	return(
		// 通过params方式传参
		<Link to=`details/${
      
      paramsId}/${
      
      name}`>详情<Link/>
		// 通过search方式传参
		<Link to=`news?searchId=${
      
      searchId}&content=${
      
      content}`>新闻<Link/>
		// 通过state方式传参
		<Link to='news' state={
    
    {
    
     stateId: stateId,  name: '张三'}}>新闻<Link/>
		<div>
			// 指定路由组件呈现的位置
			<Outlet/>
		<div/>
	)
}

// 在子组件中接收不同方式传递过来的参数
import React from "react"
import {
    
     useParams, useSearchParmas, uselocation } from 'react-router-dom'

export default function Xxxx() {
    
    
	// params接收参数
	const {
    
     paramsId, name } = useParams()
	// search接收参数
	const {
    
     search, setSearch } = useSearchParmas()
	const searchId = search.get('searchId')
	const content = search.get('content')
	// state接收参数
	const {
    
     stateId, name } = useLocation().state
	return <div>xxxx</div>
}

10.2.4 编程式路由

import React from 'react'
import {
    
     useNavigate } from 'react-router-dom'

export default function Xxxx() {
    
    
	const navigate = useNavigate()
	// 通过state方式传参
	function showDetail(m) {
    
    
		navigate('detail', {
    
    
			replace: false,
			state: {
    
    id: m.id}
		})
	}
	// 通过params方式传参
	function showDetail(m) {
    
    
		navigate(`detail/${
      
      m.id}/${
      
      m.name}`, {
    
     replace: false })
	}
	// 通过search方式传参
	function showDetail(m) {
    
    
		navigate(`detail?id=${
      
      m.id}&name=${
      
      m.name}`, {
    
     replace: false })
	}
	// 前进
	function forward() {
    
    
		navigate(1)
	}
	// 后退
	function back() {
    
    
		navigate(-1)
	}
	return (
		<div>
			<button onClick={
    
    ()=>{
    
    showDetail(m)}}>点击跳转</button>
			<button onClick={
    
    forward}>前进</button>
			<button onClick={
    
    back}>后退</button>
		</div>
	)
} 

10.2.5 路由懒加载

const LazyLoad = path=> {
    
    
	const Comp = React.lazy(()=> import(`../views/${
      
      path}`))
	return(
		<React.Suspense fallback={
    
    <>加载中。。。。</>}>
			<Comp/>
		</React.Suspense>
	)
}

<Routes>
	<Route path='/page1' element={
    
    LazyLoad('page1')} />
</Routes>

11 组件间通信

11.2 消息订阅与发布

  1. 工具库:pubsub-js
  2. 下载npm install pubsub-js --save
  3. 使用:
    • import PubSub from ‘pubsub-js’ 引入
    • PubSub.subscribe('delete', function(){}) 订阅
    • PubSub.publish('delete', data) 发布
// 手写一个简单的订阅与发布
var bus = {
    
    
	eventList: [],
	subscribe(eventName, callback) {
    
    
		this.eventList.push({
    
    
			eventName,
			callback
		})
	},
	publish(eventName, data){
    
    
		this.eventList.forEach(item=>{
    
    
			if(item.eventName === eventName) {
    
    
				item.callback(data)
			}
		})
	}
}

// 订阅消息
bus.subscribe('add', (val)=> {
    
     console.log(val) })

// 发布消息
bus.puhlish('add', 123456789	)

12. redux

  • 安装redux
npm i redux

react-redux实现自动订阅与取消订阅

13. 配置代理

npm i http-proxy-middleware --save

在src目录下,创建setupProxy.js

const proxy = require('http-proxy-middleware')

module.exports = function(app) {
    
    
  app.use(
    proxy('/api1', {
    
    
      target: 'http://xxxxxxxxxx',
      changeOrigin: true,
      pathRewrite: {
    
    '^api1': ''}
    })
  )
}
const {
    
     createProxyMiddleware }= require('http-proxy-middleware')

module.exports = function(app) {
    
    
  app.use(
    createProxyMiddleware('/api1', {
    
    
      target: 'http://xxxxxxxxxx',
      changeOrigin: true,
      pathRewrite: {
    
    '^api1': ''}
    })
  )
}

14 styled-components

all in js思想

14.1 传统思想

直接把css样式通过对象的形式写在组件内部,下面以函数式组件和类式组件分布举例

// 类式组件
import React from "react"
const box = {
    
    
  width: '200px',
  height: '200px',
  background: 'yellow'
}
class Page3 extends React.Component {
    
    
  render() {
    
    
    return (
      <>
        <h3>page3</h3>
        <div style={
    
    box}></div>
      </>
    )
  }
}
export default Page3


// 函数式组件
import React from 'react'
export default function Page4(props) {
    
    
  const box = {
    
    
    width: '400px',
  height: '400px',
  background: 'green'
  }
  return (
      <>
        <h2>page4</h2>
        <div style={
    
    box}></div>
      </>
  )
} 

在这里插入图片描述

14.2 通过styled-components

npm i styled-components

同样通过函数式组件和类式组件两种举例

// 类式组件
import React from "react"
import styled from 'styled-components'
class Page3 extends React.Component {
    
    
  render() {
    
    
    const DivBox = styled.div`
        width:200px;
        height:200px;
        background: ${
      
       this.props.background };
        .text {
          font-size: 30px;
        }`
    return (
      <>
        <h2>page3</h2>
        <DivBox>
          <span className='text'>我是一段文字</span>
        </DivBox>
      </>
    )
  }
}
export default Page3



// 函数式组件
import React from 'react'
import styled from 'styled-components'
const DivBox = styled.div`
  width: 200px;
  height:200px;
  background: ${
      
      (props)=> props.background};
  .text {
    font-size: 30px;
  }
`
export default function Page4(props) {
    
    
  return (
      <>
        <h2>page4</h2>
        <DivBox background={
    
    props.background}>
          <span className='text'>我是一段文字</span>
        </DivBox>
      </>
  )
} 


在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46801545/article/details/128872149