React基本知识点整理

React中引入样式的2种方式

1,内联样式

import React, { Component } from 'react'
export default class index extends Component {
  render() {
    return (
      
内联样式
) } }

2,声明式内联样式

import React, { Component } from 'react'
const styleCss={
  "font-size":"20px",
   color:"red"
}
export default class index extends Component {
  render() {
    return (
      
声明式内联样式
) } }

props参数传递(父传子)

//父组件
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 (
      
接受父组件传递过来的数据
) } } //子组件 import React, { Component } from 'react' export default class index extends Component { render() { console.log(this.props.data) return (
    { this.props.data.map((item)=>{ return
  • {item.name}
  • }) }
) } }

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

//父组件
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 (
      
接受子组件传递过来的数据{this.state.name}
) } } //子组件 import React, { Component } from 'react' export default class index extends Component { render() { return (
) } }

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

//父组件
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 (
			
    { messageArr.map((msgObj)=>{ return (
  • {/* 向路由组件传递params参数 */} {msgObj.title}
  • ) }) }

{/* 声明接收params参数 */}
) } } //子组件 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 (
  • ID:{id}
  • TITLE:{title}
  • CONTENT:{findResult.content}
) } }

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

//父组件
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 (
			
    { messageArr.map((msgObj)=>{ return (
  • {/* 向路由组件传递search参数 */} {msgObj.title}
  • ) }) }

{/* search参数无需声明接收,正常注册路由即可 */}
) } } //子组件 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 (
  • ID:{id}
  • TITLE:{title}
  • CONTENT:{findResult.content}
) } }

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

//父组件
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 (
			
    { messageArr.map((msgObj)=>{ return (
  • {/* 向路由组件传递state参数 */} {msgObj.title}
  • ) }) }

{/* state参数无需声明接收,正常注册路由即可 */}
) } } //子组件 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 (
  • ID:{id}
  • TITLE:{title}
  • CONTENT:{findResult.content}
) } }

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

1,一级路由

//父元素
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 (
		

React Router Demo

{/* 路由链接 */} About Home
{/* 注册路由 */} }/> }/>
) } //两上要接受的子元素 about和Home import React from 'react' export default function About() { return (

我是About的内容

) } import React from 'react' export default function Home() { return (

我是Home的内容

) }

2,重定向

//父组件
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 (
		

React Router Demo

{/* 路由链接 */} About Home
{/* 注册路由 */} }/> }/> }/>
) } //about和home import React from 'react' export default function About() { return (

我是About的内容

) } import React,{useState} from 'react' import {Navigate} from 'react-router-dom' export default function Home() { const [sum,setSum] = useState(1) return (

我是Home的内容

{sum === 2 ? :

当前sum的值是:{sum}

}
) }

3,react导航高亮

//父元素   这里的样式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 (
    

React Router Demo

About Home

新路由

{/* 注册路由 */} }> }> }>
) } //两上要接受的子元素 about和Home import React from 'react' export default function About() { return (

我是About的内容

) } import React from 'react' export default function Home() { return (

我是Home的内容

) }

4,路由的统一管理

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

export default function App() {
  //路由表的使用
  const element=useRoutes(router)
  return (
    

React Router Demo

About Home

新路由

{/* 注册路由 */} {element}
) } //router中的路由列表 import Home from "../Pages/Home" import About from "../Pages/About" import { Navigate } from "react-router-dom" export default [ { path:'/about', element: }, { path:'/Home', element: }, { path:'/', element: } ]

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

6,search传递参数

//参数传递组件
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 (
    
    { message.map((m)=>{ return (
  • {/* 使用search带参数 */} {m.title}
  • ) }) }
{/* 规定路由展示的位置 */}
) } //参数接收组件 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 (
  • {id}
  • {title}
  • {content}
) }

7,state传递参数

//传递组件
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 (
    
    { message.map((m)=>{ return (
  • {/* 使用state带参数 state里面需要包含一个对象*/} {m.title}
  • ) }) }
{/* 规定路由展示的位置 */}
) } //接受组件 import React from 'react' //需要使用useLocation import { useLocation } from 'react-router-dom' export default function Detail() { const {state:{id,title,content}}=useLocation() return (
  • {id}
  • {title}
  • {content}
) }

8,编程式路由导航

//传递组件
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 (
    
    { message.map((m)=>{ return (
  • {/* 使用state带参数 state里面需要包含一个对象*/} {m.title}
  • ) }) }
{/* 规定路由展示的位置 */}
) } //接受组件 import React from 'react' //需要使用useLocation import { useLocation } from 'react-router-dom' export default function Detail() { const {state:{id,title,content}}=useLocation() return (
  • {id}
  • {title}
  • {content}
) }

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函数中读取

//父组件 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(
      
) } } //子组件 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 (

当前求和为{this.state.count}

) } }

路由组件的lazyLoad

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

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

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

//在父组件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(
      
) } } //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 (

React Router

{/* 在React中靠路由链接实现切换组件--编写路由链接 */} About Home
{/* 注册路由 */} 正在加载中......}>
) } } //about和home两个子组件中的内容 //about import React, { Component } from 'react' export default class About extends Component { render() { return (
About
) } } //home import React, { Component } from 'react' export default class Home extends Component { render() { return (
Home
) } }

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): 参数为函数, 接收原本的状态值, 返回新的状态值, 内部用其覆盖原来的状态值

//app.js
import React, { Component } from 'react'
import './App.css'
import SetStateA from './components/Hooks'

export default class App extends Component{
  render(){
    return(
      
) } } //函数式子组件 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 (

当前求和为{count}

名字是{name}

) } export default Demo

Ref Hook

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

//父组件
import React, { Component } from 'react'
import './App.css'
import SetStateA from './components/Hooks'

export default class App extends Component{
  render(){
    return(
      
) } } //子组件 import React from 'react' //函数式组件的 function Demo(){ const myRef = React.useRef() function show(){ alert(myRef.current.value) } return (
) } export default Demo

Fragment

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

import React, { Component,Fragment } from 'react'

export default class FragMent extends Component {
  render() {
    return (
      
        
        
      
    )
  }
}

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技术, 也就是通过组件标签体传入结构  
    React中:
        使用children props: 通过组件标签体传入结构
        使用render props: 通过组件标签属性传入结构,而且可以携带数据,一般用render函数属性

### children props

    
      xxxx
    

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

### render props

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

//父组件
import React, { Component } from 'react'
import './App.css'
import SetStateA from './components/RenderProps'

export default class App extends Component{
  render(){
    return(
      
) } } //子组件 父组件中包含子组件的子组件,并实现传递数据 import React, { Component } from 'react' import './index.css' export default class Parent extends Component { render() { return (

我是props样式

这是父组件里面又包含了一个子组件

}/>
) } } class A extends Component{ state={name:"张三"} render(){ const {name} = this.state return(

我是A组件

{this.props.render(name)}

) } } class B extends Component{ render(){ return(

我是B组件{this.props.name}

) } }

错误边界

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

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

3,使用方式getDerivedStateFromError

//父组件
import React, { Component } from 'react'
import './App.css'
import SetStateA from './components/ErrorDer'

export default class App extends Component{
  render(){
    return(
      
) } } //子组件里面包含子组件 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 (
{this.state.hasError?

请稍后在试吧

:}
) } } //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 (

我是子组件

{ this.state.users.map((userObj)=>{ return

{userObj.name}

}) }
) } }

组件通信方式总结

1,组件间的关系:

- 父子组件
- 兄弟组件(非嵌套组件)
- 祖孙组件(跨级组件)

2,几种通信方式:

        1.props:
            (1).children props
            (2).render props
        2.消息订阅-发布:
            pubs-sub
        3.集中式管理:
            redux
        4.conText:
            生产者-消费者模式

3, 比较好的搭配方式:
        父子组件:props
        兄弟组件:消息订阅-发布、集中式管理
        祖孙组件(跨级组件):消息订阅-发布、集中式管理、conText(开发用的少,封装插件用的多)

你可能感兴趣的:(react.js,javascript,前端)