React基本知识点整理

props参数传递(父传子)

javascript 复制代码
//父组件
import React, { Component } from 'react'
import Child from './reac'
export default class index extends Component {
  state={
    data:[
        {id:"001",name:"张三"},
        {id:"002",name:"李四"},
        {id:"003",name:"王五"},
    ]
  }
  render() {
    return (
      <div>
        接受父组件传递过来的数据
        <Child data={this.state.data}></Child>
      </div>
    )
  }
}

//子组件
import React, { Component } from 'react'

export default class index extends Component {
  render() {
    console.log(this.props.data)
    return (
      <div>
        <ul>
          {
            this.props.data.map((item)=>{
              return <li key={item.id}>{item.name}</li>
            })
          }
        </ul>
      </div>
    )
  }
}

子组件传参给父组件(子传父)

javascript 复制代码
//父组件
import React, { Component } from 'react'
import Child from './reac'
export default class index extends Component {
  state={
    name:""
  }
  getdata=(msg)=>{
    this.setState({
        name:msg
    })
  }
  render() {
    return (
      <div>
        接受子组件传递过来的数据{this.state.name}
        <Child getdata={this.getdata}></Child>
      </div>
    )
  }
}

//子组件
import React, { Component } from 'react'

export default class index extends Component {
  render() {
    return (
      <div>
        <button onClick={()=>{this.props.getdata("哈哈")}}>点击获取数据</button>
      </div>
    )
  }
}

路由组件传递params参数 (父传子)

javascript 复制代码
//父组件
import React, { Component } from 'react'
import {Link,Route} from 'react-router-dom'
import Detail from './Detail'

export default class Message extends Component {
	state = {
		messageArr:[
			{id:'01',title:'消息1'},
			{id:'02',title:'消息2'},
			{id:'03',title:'消息3'},
		]
	}
	render() {
		const {messageArr} = this.state
		return (
			<div>
				<ul>
					{
						messageArr.map((msgObj)=>{
							return (
								<li key={msgObj.id}>
									{/* 向路由组件传递params参数 */}
									<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>
								</li>
							)
						})
					}
				</ul>
				<hr/>
				{/* 声明接收params参数 */}
				<Route path="/home/message/detail/:id/:title" component={Detail}/>
			</div>
		)
	}
}

//子组件
import React, { Component } from 'react'

const DetailData = [
	{id:'01',content:'张三'},
	{id:'02',content:'李四'},
	{id:'03',content:'王五'}
]
export default class Detail extends Component {
	render() {
		console.log(this.props);
		// 接收params参数
		const {id,title} = this.props.match.params
		const findResult = DetailData.find((detailObj)=>{
			return detailObj.id === id
		})
		return (
			<ul>
				<li>ID:{id}</li>
				<li>TITLE:{title}</li>
				<li>CONTENT:{findResult.content}</li>
			</ul>
		)
	}
}

路由组件传递search参数(父传子)

javascript 复制代码
//父组件
import React, { Component } from 'react'
import {Link,Route} from 'react-router-dom'
import Detail from './Detail'

export default class Message extends Component {
	state = {
		messageArr:[
			{id:'01',title:'消息1'},
			{id:'02',title:'消息2'},
			{id:'03',title:'消息3'},
		]
	}
	render() {
		const {messageArr} = this.state
		return (
			<div>
				<ul>
					{
						messageArr.map((msgObj)=>{
							return (
								<li key={msgObj.id}>

									{/* 向路由组件传递search参数 */}
									<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>

								</li>
							)
						})
					}
				</ul>
				<hr/>

				{/* search参数无需声明接收,正常注册路由即可 */}
				<Route path="/home/message/detail" component={Detail}/>

			</div>
		)
	}
}

//子组件
import React, { Component } from 'react'
import qs from 'querystring'

const DetailData = [
	{id:'01',content:'张三'},
	{id:'02',content:'李四'},
	{id:'03',content:'王五'}
]
export default class Detail extends Component {
	render() {
		console.log(this.props);

		// 接收search参数
		const {search} = this.props.location
		const {id,title} = qs.parse(search.slice(1))

		const findResult = DetailData.find((detailObj)=>{
			return detailObj.id === id
		})
		return (
			<ul>
				<li>ID:{id}</li>
				<li>TITLE:{title}</li>
				<li>CONTENT:{findResult.content}</li>
			</ul>
		)
	}
}

路由组件传递state参数(父传子)

javascript 复制代码
//父组件
import React, { Component } from 'react'
import {Link,Route} from 'react-router-dom'
import Detail from './Detail'

export default class Message extends Component {
	state = {
		messageArr:[
			{id:'01',title:'消息1'},
			{id:'02',title:'消息2'},
			{id:'03',title:'消息3'},
		]
	}
	render() {
		const {messageArr} = this.state
		return (
			<div>
				<ul>
					{
						messageArr.map((msgObj)=>{
							return (
								<li key={msgObj.id}>
									{/* 向路由组件传递state参数 */}
									<Link to={{pathname:'/home/message/detail',state:{id:msgObj.id,title:msgObj.title}}}>{msgObj.title}</Link>

								</li>
							)
						})
					}
				</ul>
				<hr/>
				{/* state参数无需声明接收,正常注册路由即可 */}
				<Route path="/home/message/detail" component={Detail}/>

			</div>
		)
	}
}

//子组件
import React, { Component } from 'react'
// import qs from 'querystring'

const DetailData = [
	{id:'01',content:'你好,中国'},
	{id:'02',content:'你好,尚硅谷'},
	{id:'03',content:'你好,未来的自己'}
]
export default class Detail extends Component {
	render() {
		console.log(this.props);
		// 接收state参数
		const {id,title} = this.props.location.state || {}

		const findResult = DetailData.find((detailObj)=>{
			return detailObj.id === id
		}) || {}
		return (
			<ul>
				<li>ID:{id}</li>
				<li>TITLE:{title}</li>
				<li>CONTENT:{findResult.content}</li>
			</ul>
		)
	}
}

路由的其本知识点(react-router6)

1,一级路由

javascript 复制代码
//父元素
import React from 'react'
import {NavLink,Routes,Route} from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'

export default function App() {
	return (
		<div>
			<div className="row">
				<div className="col-xs-offset-2 col-xs-8">
					<div className="page-header"><h2>React Router Demo</h2></div>
				</div>
			</div>
			<div className="row">
				<div className="col-xs-2 col-xs-offset-2">
					<div className="list-group">
						{/* 路由链接 */}
						<NavLink className="list-group-item" to="/about">About</NavLink>
						<NavLink className="list-group-item" to="/home">Home</NavLink>
					</div>
				</div>
				<div className="col-xs-6">
					<div className="panel">
						<div className="panel-body">
							{/* 注册路由 */}
							<Routes>
								<Route path="/about" element={<About/>}/>
								<Route path="/home" element={<Home/>}/>
							</Routes>
						</div>
					</div>
				</div>
			</div>
		</div>
	)
}

//两上要接受的子元素 about和Home
import React from 'react'

export default function About() {
	return (
		<h3>我是About的内容</h3>
	)
}

import React from 'react'

export default function Home() {
	return (
		<h3>我是Home的内容</h3>
	)
}

2,重定向

javascript 复制代码
//父组件
import React from 'react'
import {NavLink,Routes,Route,Navigate} from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'

export default function App() {
	return (
		<div>
			<div className="row">
				<div className="col-xs-offset-2 col-xs-8">
					<div className="page-header"><h2>React Router Demo</h2></div>
				</div>
			</div>
			<div className="row">
				<div className="col-xs-2 col-xs-offset-2">
					<div className="list-group">
						{/* 路由链接 */}
						<NavLink className="list-group-item" to="/about">About</NavLink>
						<NavLink className="list-group-item" to="/home">Home</NavLink>
					</div>
				</div>
				<div className="col-xs-6">
					<div className="panel">
						<div className="panel-body">
							{/* 注册路由 */}
							<Routes>
								<Route path="/ABOUT" element={<About/>}/>
								<Route path="/home" element={<Home/>}/>
								<Route path="/" element={<Navigate to="/about"/>}/>
							</Routes>
						</div>
					</div>
				</div>
			</div>
		</div>
	)
}

//about和home
import React from 'react'

export default function About() {
	return (
		<h3>我是About的内容</h3>
	)
}

import React,{useState} from 'react'
import {Navigate} from 'react-router-dom'

export default function Home() {
	const [sum,setSum] = useState(1)
	return (
		<div>
			<h3>我是Home的内容</h3>
			{sum === 2 ? <Navigate to="/about" replace={true}/> : <h4>当前sum的值是:{sum}</h4>}
			<button onClick={()=>setSum(2)}>点我将sum变为2</button>
		</div>
	)
}

3,react导航高亮

javascript 复制代码
//父元素   这里的样式reactStyle需要提前声明

import React from 'react'
//引入路由
import {NavLink,Routes,Route,Navigate} from 'react-router-dom'
//引入组件
import About from './Pages/About'
import Home from './Pages/Home'

export default function App() {
  function computetClassStyle({isActive}){
    return isActive?'list-group-item reactStyle':'list-group-item'
  }
  return (
    <div>
      <div>
        <div className="row">
          <div className="col-xs-offset-2 col-xs-8">
            <div className="page-header"><h2>React Router Demo</h2></div>
          </div>
        </div>
        <div className="row">
          <div className="col-xs-2 col-xs-offset-2">
            <div className="list-group">
              <NavLink className={computetClassStyle} to="about">About</NavLink>
              <NavLink className={computetClassStyle} to="/home">Home</NavLink>
            </div>
          </div>
          <div className="col-xs-6">
            <div className="panel">
              <div className="panel-body">
                <h3>新路由</h3>
                {/* 注册路由 */}
                <Routes>
                  <Route path='/About' element={<About></About>}></Route>
                  <Route path='/Home' element={<Home></Home>}></Route>
                  <Route path='/' element={<Navigate to="/About"></Navigate>}></Route>
                </Routes>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}



//两上要接受的子元素 about和Home
import React from 'react'

export default function About() {
	return (
		<h3>我是About的内容</h3>
	)
}

import React from 'react'

export default function Home() {
	return (
		<h3>我是Home的内容</h3>
	)
}

4,路由的统一管理

javascript 复制代码
//在主文件中使用
import React from 'react'
//引入路由
import {NavLink,useRoutes} from 'react-router-dom'
import router from './router'

export default function App() {
  //路由表的使用
  const element=useRoutes(router)
  return (
    <div>
      <div>
        <div className="row">
          <div className="col-xs-offset-2 col-xs-8">
            <div className="page-header"><h2>React Router Demo</h2></div>
          </div>
        </div>
        <div className="row">
          <div className="col-xs-2 col-xs-offset-2">
            <div className="list-group">
              <NavLink className="list-group-item" to="about">About</NavLink>
              <NavLink className="list-group-item" to="/home">Home</NavLink>
            </div>
          </div>
          <div className="col-xs-6">
            <div className="panel">
              <div className="panel-body">
                <h3>新路由</h3>
                {/* 注册路由 */}
                {element}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

//router中的路由列表
import Home from "../Pages/Home"
import About from "../Pages/About"
import { Navigate } from "react-router-dom"
export default [
    {
        path:'/about',
        element:<About></About>
    },
    {
        path:'/Home',
        element:<Home></Home>
    },
    {
        path:'/',
        element:<Navigate to="/about"></Navigate>
    }
]

5,路由的嵌套,父里面包含子

6,search传递参数

javascript 复制代码
//参数传递组件
import React,{useState} from 'react'
import { Link,Outlet } from 'react-router-dom'

export default function Message() {
  const [message] =useState([
	{id:'001',title:'张三',content:'kdjfkdfj'},
	{id:'002',title:'李四',content:'45612'},
	{id:'003',title:'王五',content:'kdjferetdkdfj'},
	{id:'004',title:'赵六',content:'kdjadffkdfj'}
  ])
  return (
    <div>
      <ul>
		{
			message.map((m)=>{
				return (
					<li key={m.id}>
						{/* 使用search带参数 */}
						<Link to={`detail?id=${m.id}&title=${m.title}&content=${m.content}`}>{m.title}</Link>
					</li>
				)
			})
		}			
	 </ul>
	 {/* 规定路由展示的位置 */}
	 <Outlet></Outlet>
    </div>
  )
}

//参数接收组件
import React from 'react'
import { useSearchParams } from 'react-router-dom'

export default function Detail() {
  const [search]=useSearchParams()
  console.log(search.get('id'))
  const id=search.get('id')
  const title=search.get('title')
  const content=search.get('content')
  return (
    <div>
      <ul>
        <li>{id}</li>
        <li>{title}</li>
        <li>{content}</li>
      </ul>
    </div>
  )
}

7,state传递参数

javascript 复制代码
//传递组件
import React,{useState} from 'react'
import { Link,Outlet } from 'react-router-dom'

export default function Message() {
  const [message] =useState([
	{id:'001',title:'张三',content:'kdjfkdfj'},
	{id:'002',title:'李四',content:'45612'},
	{id:'003',title:'王五',content:'kdjferetdkdfj'},
	{id:'004',title:'赵六',content:'kdjadffkdfj'}
  ])
  return (
    <div>
      <ul>
		{
			message.map((m)=>{
				return (
					<li key={m.id}>
						{/* 使用state带参数 state里面需要包含一个对象*/}
						<Link to="detail" state={{
							id:m.id,
							title:m.title,
							content:m.content
						}}>{m.title}</Link>
					</li>
				)
			})
		}			
	 </ul>
	 {/* 规定路由展示的位置 */}
	 <Outlet></Outlet>
    </div>
  )
}

//接受组件
import React from 'react'
//需要使用useLocation
import { useLocation } from 'react-router-dom'

export default function Detail() {

  const {state:{id,title,content}}=useLocation()
  return (
    <div>
      <ul>
        <li>{id}</li>
        <li>{title}</li>
        <li>{content}</li>
      </ul>
    </div>
  )
}

8,编程式路由导航

javascript 复制代码
//传递组件
import React,{useState} from 'react'
import { Link,Outlet,useNavigate } from 'react-router-dom'

export default function Message() {
  const [message] =useState([
	{id:'001',title:'张三',content:'kdjfkdfj'},
	{id:'002',title:'李四',content:'45612'},
	{id:'003',title:'王五',content:'kdjferetdkdfj'},
	{id:'004',title:'赵六',content:'kdjadffkdfj'}
  ])
  //编辑式路由导航,需要借助useNavigate
  //2,useNavigate还可以实现前进和后退 传入对应的参数即可
  const Nav=useNavigate()
  function showDetail(m){
	Nav('Detail',{
		replace:false,
		state:{
			id:m.id,
			title:m.title,
			content:m.content
		}
	})
  }
  return (
    <div>
      <ul>
		{
			message.map((m)=>{
				return (
					<li key={m.id}>
						{/* 使用state带参数 state里面需要包含一个对象*/}
						<Link to="detail" state={{
							id:m.id,
							title:m.title,
							content:m.content
						}}>{m.title}</Link>
						<button onClick={()=>showDetail(m)}>查看详情</button>
					</li>
				)
			})
		}			
	 </ul>
	 {/* 规定路由展示的位置 */}
	 <Outlet></Outlet>
    </div>
  )
}

//接受组件
import React from 'react'
//需要使用useLocation
import { useLocation } from 'react-router-dom'

export default function Detail() {

  const {state:{id,title,content}}=useLocation()
  return (
    <div>
      <ul>
        <li>{id}</li>
        <li>{title}</li>
        <li>{content}</li>
      </ul>
    </div>
  )
}

setState更新状态的2种写法

(1). setState(stateChange, [callback])------对象式的setState

1.stateChange为状态改变对象(该对象可以体现出状态的更改)

2.callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用

(2). setState(updater, [callback])------函数式的setState

1.updater为返回stateChange对象的函数。

2.updater可以接收到state和props。

4.callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用。

总结:

1.对象式的setState是函数式的setState的简写方式(语法糖)

2.使用原则:

(1).如果新状态不依赖于原状态 ===> 使用对象方式

(2).如果新状态依赖于原状态 ===> 使用函数方式

(3).如果需要在setState()执行后获取最新的状态数据,

要在第二个callback函数中读取

javascript 复制代码
//父组件 App.js
//import logo from './logo.svg';
import React, { Component } from 'react'
import './App.css'
import SetStateA from './components/SetState1'

export default class App extends Component{
 
  render(){
    return(
      <div>
		    <SetStateA></SetStateA>
	  </div>
    )
  }
}


//子组件 components
import React, { Component } from 'react'

export default class SetStateA extends Component {
  //对象式的setState
  state={count:0}
  add=()=>{
    //获取原来count的值
    const {count}=this.state
    //更新状态
    this.setState({count:count+1},()=>{
        console.log('监测值的改变'+this.state.count)
    })
  }
  //函数式的写法
  addNum=()=>{
    this.setState((state,props)=>{
        console.log(props)
        return {count:state.count+1}
    })
  }
  render() {
    return (
      <div>
        <h1>当前求和为{this.state.count}</h1>
        <button onClick={this.add}>对象式</button>
        <button onClick={this.addNum}>函数式</button>
      </div>
    )
  }
}

路由组件的lazyLoad

1,lazyLoad主要用于大量路由切换的时候,根据需要加载对应的路由信息

2,通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包

3,通过<Suspense>指定在加载得到路由

javascript 复制代码
//在父组件App.js中引入子组件
//import logo from './logo.svg';
import React, { Component } from 'react'
import './App.css'
import Lazyload from './components/Layload'

export default class App extends Component{
  render(){
    return(
      <div>
        <Lazyload></Lazyload>
	  </div>
    )
  }
}
//lazyload组件里面包含两个子组件home和about
import React, { Component,lazy,Suspense } from 'react'
import {NavLink,Route} from 'react-router-dom'
//以前的加载方式
// import Home from './Home'
// import About from './About'

//使用lazy
const Home=lazy(()=>import('./Home'))
const About =lazy(()=>import('./About'))

export default class Lazyload extends Component {
	render() {
		return (
			<div>
				<div className="row">
					<div className="col-xs-offset-2 col-xs-8">
						<div className="page-header"><h2>React Router</h2></div>
					</div>
				</div>
				<div className="row">
					<div className="col-xs-2 col-xs-offset-2">
						<div className="list-group">

							{/* 在React中靠路由链接实现切换组件--编写路由链接 */}
							<NavLink className="list-group-item" to="/About">About</NavLink>
							<NavLink className="list-group-item" to="/Home">Home</NavLink>
						</div>
					</div>
					<div className="col-xs-6">
						<div className="panel">
							<div className="panel-body">
								{/* 注册路由 */}
                                <Suspense fallback={<h1>正在加载中......</h1>}>
                                    <Route path="/About" component={About}/>
                                    <Route path="/Home" component={Home}/>
                                </Suspense>
							</div>
						</div>
					</div>
				</div>
			</div>
		)
	}
}

//about和home两个子组件中的内容
//about
import React, { Component } from 'react'

export default class About extends Component {
  render() {
    return (
      <div>
        About
      </div>
    )
  }
}
//home
import React, { Component } from 'react'

export default class Home extends Component {
  render() {
    return (
      <div>
        Home
      </div>
    )
  }
}

State Hook

(1). State Hook让函数组件也可以有state状态, 并进行状态数据的读写操作
(2). 语法: const [xxx, setXxx] = React.useState(initValue)
(3). useState()说明:
参数: 第一次初始化指定的值在内部作缓存
返回值: 包含2个元素的数组, 第1个为内部当前状态值, 第2个为更新状态值的函数
(4). setXxx()2种写法:
setXxx(newValue): 参数为非函数值, 直接指定新的状态值, 内部用其覆盖原来的状态值
setXxx(value => newValue): 参数为函数, 接收原本的状态值, 返回新的状态值, 内部用其覆盖原来的状态值

javascript 复制代码
//app.js
import React, { Component } from 'react'
import './App.css'
import SetStateA from './components/Hooks'

export default class App extends Component{
  render(){
    return(
      <div>
		    <SetStateA></SetStateA>
	  </div>
    )
  }
}

//函数式子组件
import React from 'react'
//函数式组件的
function Demo(){
    const [count,setCount] = React.useState(0)
    const [name,setName]=React.useState('张三')
    //console.log(count,setCount)
    function add(){
        console.log("点击事件")
        //setCount(count+1)//第一种写法
        //第二种写法
        setCount((count)=>{
            return count+1
        })
    }
    function changeName(){
        setName("李四")
    }
    return (
        <div>
         <h2>当前求和为{count}</h2>
         <h2>名字是{name}</h2>
         <button onClick={add}>加1</button>
         <button onClick={changeName}>点我改名字</button>
       </div>
    )
}
export default Demo

Ref Hook

(1). Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据
(2). 语法: const refContainer = useRef()

javascript 复制代码
//父组件
import React, { Component } from 'react'
import './App.css'
import SetStateA from './components/Hooks'

export default class App extends Component{
  render(){
    return(
      <div>
		    <SetStateA></SetStateA>
	  </div>
    )
  }
}
//子组件
import React from 'react'
//函数式组件的
function Demo(){
    const myRef = React.useRef()
    function show(){
       alert(myRef.current.value)
    }
    return (
        <div>
         <input type="text" ref={myRef} />
         <button onClick={show}>点我提示</button>
       </div>
    )
}
export default Demo

Fragment

可用于取代一个真实的DOM根标签

javascript 复制代码
import React, { Component,Fragment } from 'react'

export default class FragMent extends Component {
  render() {
    return (
      <Fragment>
        <input type="text" />
        <button>点击</button>
      </Fragment>
    )
  }
}

Component

> 1. 只要执行setState(),即使不改变状态数据, 组件也会重新render() ==> 效率低
>
> 2. 只当前组件重新render(), 就会自动重新render子组件,纵使子组件没有用到父组件的任何数据 ==> 效率低

效率高的做法

> 只有当组件的state或props数据发生改变时才重新render()

原因

> Component中的shouldComponentUpdate()总是返回true

解决

办法1:
重写shouldComponentUpdate()方法
比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false
办法2:
使用PureComponent
PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true
注意:
只是进行state和props数据的浅比较, 如果只是数据对象内部数据变了, 返回false
不要直接修改state数据, 而是要产生新数据
项目中一般使用PureComponent来优化

render props(向组件内部动态传入带内容的结构)

Vue中:
使用slot技术, 也就是通过组件标签体传入结构 <A><B/></A>
React中:
使用children props: 通过组件标签体传入结构
使用render props: 通过组件标签属性传入结构,而且可以携带数据,一般用render函数属性

children props

<A>
<B>xxxx</B>
</A>
{this.props.children}
问题: 如果B组件需要A组件内的数据, ==> 做不到

render props

<A render={(data) => <C data={data}></C>}></A>
A组件: {this.props.render(内部state数据)}
C组件: 读取A组件传入的数据显示 {this.props.data}

javascript 复制代码
//父组件
import React, { Component } from 'react'
import './App.css'
import SetStateA from './components/RenderProps'

export default class App extends Component{
  render(){
    return(
      <div>
		    <SetStateA></SetStateA>
	  </div>
    )
  }
}

//子组件  父组件中包含子组件的子组件,并实现传递数据
import React, { Component } from 'react'
import './index.css'

export default class Parent extends Component {
  render() {
    return (
      <div className='parent'>
        <h3>我是props样式</h3>
        <h4>这是父组件里面又包含了一个子组件</h4>
        <A render={(name)=><B name={name}/>}/>
      </div>
    )
  }
}

class A extends Component{
    state={name:"张三"}
    render(){
        const {name} = this.state
        return(
            <div className='a'>
                <h3>我是A组件</h3>
                <h4>{this.props.render(name)}</h4>
            </div>
        )
    }
}

class B extends Component{
    render(){
        return(
            <div className='b'>
                <h3>我是B组件{this.props.name}</h3>
            </div>
        )
    }
} 

错误边界

1,错误边界(Error boundary):用来捕获后代组件错误,渲染出备用页面

2,只能捕获后代组件生命周期产生的错误,不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误

3,使用方式getDerivedStateFromError

javascript 复制代码
//父组件
import React, { Component } from 'react'
import './App.css'
import SetStateA from './components/ErrorDer'

export default class App extends Component{
  render(){
    return(
      <div>
		    <SetStateA></SetStateA>
	  </div>
    )
  }
}


//子组件里面包含子组件
import React, { Component } from 'react'
import Child from './child'

export default class index extends Component {
  //用于标识子组件是否产生错误
  state={
    hasError:""
  }
  static getDerivedStateFromError(error){
    console.log("@@@",error)
    return {hasError:error}
  }
  //用于子组件会出现的问题,在父组件提交做预判
  render() {
    return (
      <div>
        {this.state.hasError?<h2>请稍后在试吧</h2>:<Child></Child>}
      </div>
    )
  }
}
//child组件
import React, { Component } from 'react'

export default class index extends Component {
  //对应的子组件里面出现的错误
  state={
    // users:[
    //     {id:"01",name:"张三"},
    //     {id:"02",name:"李四"},
    //     {id:"03",name:"王五"}
    // ]
    users:'张三'
  }
  //只能处理生命周期里面处理的错误  一般用于处理render里面出现的错误
  render() {
    return (
      <div>
        <h2>我是子组件</h2>
        {
            this.state.users.map((userObj)=>{
                return <h3 key={userObj.id}>{userObj.name}</h3>
            })
        }
      </div>
    )
  }
}

组件通信方式总结

1,组件间的关系:

  • 父子组件

  • 兄弟组件(非嵌套组件)

  • 祖孙组件(跨级组件)

2,几种通信方式:

1.props:

(1).children props

(2).render props

2.消息订阅-发布:

pubs-sub

3.集中式管理:

redux

4.conText:

生产者-消费者模式

3, 比较好的搭配方式:

父子组件:props

兄弟组件:消息订阅-发布、集中式管理

祖孙组件(跨级组件):消息订阅-发布、集中式管理、conText(开发用的少,封装插件用的多)

相关推荐
Boilermaker19926 分钟前
【Java EE】SpringIoC
前端·数据库·spring
中微子17 分钟前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上102432 分钟前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y1 小时前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁1 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry1 小时前
Fetch 笔记
前端·javascript
拾光拾趣录1 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟1 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan1 小时前
一文了解什么是Dart
前端·flutter·dart
Patrick_Wilson1 小时前
青苔漫染待客迟
前端·设计模式·架构