• React基础


    创建React项目

    第一种方式

    npm i -g create-react-app
    //your-project-name 项目名称
    create-react-app your-project-name
    
    • 1
    • 2
    • 3

    第二种方式

    //your-project-name 项目名称
    npx creat-react-app your-project-name
    
    • 1
    • 2

    React页面渲染

    步骤
    1.导入包
    2.创建react元素
    3.渲染元素到某个dom上

    React内置了JSX

    1.jsx必须要有一个根节点
    2.属性名不能用js中的关键字,例如class,for

    //class类   写为className
    <div className="App-header"></div>
    
    • 1
    • 2

    3.单标签要闭合
    4.换行建议使用()包裹
    5.老版本(16.8)之前,先引入react才能使用jsx

    jsx-嵌入表达式

    <div>{}<div>
    
    • 1

    {}中可以写:
    1.表达式
    2.其他的jsx表达式
    3.注释
    不可以写:
    1.对象
    2.js语句 if/switch/变量申明

    jsx条件渲染

    if/else
    三元运算符
    逻辑与运算符
    switch case

    必须要有一个根节点

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    
    function App1() {
      // const num = Math.random()
      const flag = true
      const fn = () => {
        if(flag){
          return <p>成功</p>
        }else{
          return <p>失败</p>
        }
      }
      const skills = [
        {id:1,name:'html'},
        {id:2,name:'css'},
        {id:3,name:'js'}
      ]
      // const list = [
      //   
      技能{skills[0].id}:{skills[0].name}
    ,
    //
      技能{skills[1].id}:{skills[1].name}
    ,
    //
      技能{skills[2].id}:{skills[2].name}
    // ] // const list = skills.map(item => { // return
      技能{item.id}:{item.name}
    // }) const list = skills.map(item => <ol key={item.id}>技能{item.id}:{item.name}</ol> ) return ( <div className="App"> {list} {fn} </div> ); } const root = ReactDOM.createRoot(document.getElementById('root')); // 严格模式 root.render( <App1></App1> );
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    jsx中的样式

     //style
     <div style={{position:'absolute',left:'10px'}} ></div>
    
    //className
    <div className = "mystyle"></div>
    
    <style>
    	.mystyle{
    		position:'absolute',left:'10px'
    	}
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    JSX中使用本地图片

    import logo from './logo.svg';
    <img src={logo} className="App-logo" alt="logo" />
    
    • 1
    • 2

    React组件

    组件类型

    1.基础组件
    2.业务组件
    3.区块组件
    4.页面组件

    React创建组件的两种方式

    1.函数式组件(js是函数或箭头函数)

    约定1.函数首字母大写
    约定2.必须有返回值

      const Com1 = ()=> {
        return <div>函数组件</div>
      }
    
    • 1
    • 2
    • 3
    2.类组件

    注意:
    1.类名必须以大写字母开头
    2.render必须要有返回值

       class Com2 extends React.Component {
            render () {
                return <div>类组件</div>
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    React有状态组件和无状态组件

    状态:是用来描述事物在 某一时刻的形态 的 数据,一般称为state
    状态的特点:状态能被改变,改变之后视图会对应的变化

    有状态组件

    能够定义state的组件,类组件就是有状态的组件
    创建state第一种方式:

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    
    // 类组件
    class Com2 extends React.Component {
      state = {
    	  num:100,
    	  obj:{
    	     name:'小花'
    	  }
      }
      render () {
        const { num, msg, obj } = this.state
        return (
          <div>
            <p>num:{num}</p>
            <p>msd:{msg}</p>
            <p>obj的名字:{obj.name}</p>
          </div>
        )
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    创建state第二种方式:

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    
    // 类组件
    class Com2 extends React.Component {
      constructor (){
        super()
        this.state ={
          num:1,
          msg:'状态信息',
          obj:{
          	name:'小花'
          }
        }
      }
      render () {
        const { num, msg, obj } = this.state
        return (
          <div>
            <p>num:{num}</p>
            <p>msd:{msg}</p>
            <p>obj的名字:{obj.name}</p>
          </div>
        )
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    无状态组件

    不能定义state的组件,函数组件又叫无状态组件
    应用场景:
    1.组件本身不需要状态,例如渲染一段固定内容
    2.组件本身没有状态,可以从外部传入

    React中事件绑定

    //语法
    <元素 事件名1={ 事件处理函数1 } 事件名2={ 事件处理函数2 }>
    
    • 1
    • 2
    class Com2 extends React.Component {
      onClick () {
      	console.log('修改状态')
      }
      render () {
        const { num, msg, obj } = this.state
        return (
          <div>
            <button onClick={this.hClick()}>修改状态</button>
    		//上面一句代码 等价下一句代码
    		<button onClick={undefined}>修改状态</button>
          </div>
        )
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    注意:
    1.React事件名采用驼峰命名法
    2.在类中补充方法
    3.this.fn不要加括号

    事件对象

    class Com2 extends React.Component {
      hClick (e) {
      	//阻止默认行为
      	e.preventDefault()
      	//阻止冒泡行为
      	console.log('修改状态')
      }
      render () {
        return (
          <div>
            <button onClick={this.hClick}>修改状态</button>
          </div>
        )
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    事件中this的指向

    class Com2 extends React.Component {
      hClick( e) {
      	console.log(this)  //undefined
      }
      render () {
      	console.log(this)  //
        return (
          <div>
            <button onClick={this.hClick}>修改状态</button>
          </div>
        )
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    class内部启用了严格模式
    render方法指向当前react组件

    解决React事件处理程序中this指向问题主要有三种方式:

    1.在外层补充箭头函数
    2.Function.prototype.bind()
    3.class的实例方法(推荐)

     {/* 在外层补充箭头函数 */}
     <button onClick={()=>{this.h2()}}>点我-箭头函数</button>
     {/* bind */}
     <button onClick={this.h3.bind(this)}>点我-bind</button>
      {/* 实例方法 */}
      <button onClick={this.h4}>点我-bind</button>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    react 核心理念状态不可变

    不能直接修改state改变视图,需要通过setState()修改状态

    class Com2 extends React.Component {
      constructor (){
        super()
        this.state ={
          num:1
        }
      }
      hClick = () => {
        this.setState({
          num: this.state.num+1
        })
      }
      render () {
      	const { num } = this.state
        return (
          <div>
           <p>num:{num}</p>
            <button onClick={this.hClick}>修改状态</button>
          </div>
        )
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    非受控组件-ref

    借助 ref,使用原生DOM的方式来获取表单元素的值。使用步骤如下:
    1.导入方法: import { createRef } from 'react';
    2.调用createRef方法创建引用, 假设名为refDom , const refDom = createRef()
    3.refDom设置给表单元素的ref属性 ,
    4.通过refDom.current.value来获取值,

    //class组件
    class Com2 extends React.Component {
      refDom = createRef()
      constructor (){
        super()
        this.state ={
          num:1
        }
      }
      fn(){
        console.log('点击',this.refDom.value)
      }
      render () {
        return (
          <div>
            <input ref={this.refDom} type="text"></input>
            <button onClick={()=>{this.fn()}}>点击按钮</button>
          </div>
        )
      }
    }
    
    // 函数组件
    const Com1 = ()=> {
      const refDom = createRef()
      const fn = () => {
        console.log('点击',refDom.current.value)
      }
      return (<div>
        函数组件
        <input type="text" ref={refDom} />
        <button onClick={fn}>点击按钮</button>
      </div>)
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    受控组件

    使用受控组件的方式获取表单的值
    正常情况下,表单元素input是可用任意输入内容,可用理解为input自己维护它的状态(value)
    受控组件的思路:
    1.在state中定义状态
    2.将state中的状态与表单元素的value绑定在一起,进而通过state中的状态来控制表单元素

    //class组件
    class Com2 extends React.Component {
      refDom = createRef()
      constructor (){
        super()
        this.state ={
          msg:''
        }
      }
      fn2 = (e)=>{
        this.setState({
          msg:e.target.value
        })
      }
      render () {
       const { msg } = this.state
        return (
          <div>
          	<input onChange={this.fn2} type="text" value={this.state.msg}></input>
          </div>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    React组件

    组件拆分到文件

    1.创建组件

    //Header.js
    import React, { Component } from 'react'
    export default class Header extends Component {
      render() {
        return (
          <div>
            这是一个组件
          </div>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.使用组件

    import Header from './Header';
    //部分代码
     return (
        <div className="App">
          <Header />
        </div>
      );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    React组件通讯的三种方式

    1.父子组件之间
    父传子 props

    父组件-传入数据

    <子组件 自定义属性1={1} 自定义属性1={2}>
    
    • 1
    export default class Parents extends Component {
      render() {
        return (
          <div>
            父组件
            <Son age={18} name="小花" />
          </div>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    函数式子组件接受数据:props

    function Son(props){
    	return <div>子组件</div>
    }
    
    • 1
    • 2
    • 3

    Class子组件接受数据:this.props

    //类组件部分代码
    render() {
        const { age, name } = this.props
        return (
            return <div>子组件</div>
        )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    子传父 props

    利用回调函数,父组件提供回调,子组件调用,将传递的数据作为回调函数的参数。

    //父组件
    export default class Parents extends Component {
      state = {
      	num:1
      }
      f = (num) =>{
      	this.setState({num})
      }
      render() {
        return (
          <div>
            {this.state.num}
             <Son f={this.f} />
          </div>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Class子组件接受数据:this.props

    //子组件部分代码
    hClick = () =>{
    	this.props.f(1)
    }
    render() {
        const { age, name } = this.props
        return (
            return (<div>
            <button onClick={this.hClick}>1传给父组件</button>
            </div>)
        )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    2.兄弟组件之间
    	状态提升,定义在子组件状态,提升到父组件中,以父组件作为桥梁,让兄弟之间进行通讯。
    
    • 1
    //父组件
    export default class Parents extends Component {
      state = {
      	num:1
      }
      f = (num) =>{
      	this.setState({num})
      }
      render() {
        return (
          <div>
            {this.state.num}
             <Son1 f={this.f} />
             <Son2 num={this.state.num} />
          </div>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    //子组件部分代码
    hClick = () =>{
    	this.props.f(1)
    }
    render() {
        const { age, name } = this.props
        return (
            return (<div>
            <button onClick={this.hClick}>1传给父组件</button>
            </div>)
        )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    //son1子组件部分代码
    hClick = () =>{
    	this.props.f(1)
    }
    render() {
        const { age, name } = this.props
        return (
            return (<div>
            <button onClick={this.hClick}>1通过父组件传给兄弟组件</button>
            </div>)
        )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    //son2子组件部分代码
    render() {
        return (
            return (<div>
            {this.props.num}
            </div>)
        )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    3.跨组件层级Context()
    import { createContext } form  'react'
    const { Provider, Consumer } = createContext()
    
    • 1
    • 2

    Provider包裹根组件

     return (
        <div>
         // store={store}  需要传的值
        <Provider store={store}>
          <App></App>  
        </Provider>
        
        </div>
      )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    任意后代组件,可使用Consumer组件包裹整个组件

    render(){
     return (
        <Consumer>
      		{
      			(data) => {
      				return <div>这里是组件的内容,data是传过来的数据</div>
      			}
      		}
        </Consumer>
      )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    React中 props基本使用

    使用props语法能够将数据从父组件传到子组件

    props注意事项:
    1.可以传递任意数据(包括函数,jsx)
    2.props是只读属性(不可以修改)
    数据是谁的谁去改
    3.单向数据流 自上而下

    props中的children属性 (传结构)

    只要组件有子节点,props就有该属性

    <Girl age={18} name="小花">
       <h5>h5标签</h5>
     </Girl>
     //props.children
    
    • 1
    • 2
    • 3
    • 4
    //Girl 组件
    function Girl(props){
    	return <div>{props.children}</div>
    	//等价 
    h5标签
    } //可以传结构
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    propstype 校验

    improt PropTypes from 'prop-types'
    // App为组件的名字
    App.propsTypes = {
    	pagesize:PropTypes.number
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    props给组件设置默认值 的两种方式

    1.defaultProps

    //组件App部分代码
    // App为组件的名字
    App.propsTypes = {
    	pagesize:PropTypes.number
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.结构赋值的默认值

    const {pagesize=10} = this.props
    
    • 1
    //组件App部分代码
    //设置默认值
    APP.defaultProps = {
        pagesize:10
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    React生命周期

    执行时机:组件创建时(页面加载时)

    生命周期

    挂载时:
    constructor()---->render()---->ComponentDidMount()
    
    • 1

    1. constructor()
    创建组件时最先执行
    作用:1.初始化state 2.创建Ref
    2. render()
    每次组件渲染都会触发
    作用:渲染ui
    3.ComponentDidMount()
    组件挂载(完成DOM渲染)后
    作用:1.发送网络请求 2.DOM操作

    更新时
    render()----> ComponentDidUpdate()
    
    • 1

    三种情况下可以导致更新 new props(父组件传入的数据发生改变) 、 this.setState()this.forceUpdate()

    卸载时
    ComponentWillUnmount()
    
    • 1

    可以清除定时器 移除事件 比如监听器

    setState

    this.setState(
      { link: 'http://www.chao99.top' },
      () => console.log('这是回调函数')
    )
    
    • 1
    • 2
    • 3
    • 4

    setState三个特点

    1. 可以表现为异步
      setState调用之后,并不会立即去修改state的值,也不会立即更新DOM
    2. 多次调用会合并,统一后触发一次render()
    3. 使用不当会造成死循环 在render()ComponentDidUpdate()中调用setState()会导致死循环

    setState第二个参数是回调函数

    该函数会在setState函数调用完成并且组件开始重渲染的时候被调用,我们可以用该函数来监听渲染是否完成

    React hooks

    hooks 是一些函数 可以让在函数组件中“钩入”React state及生命周期的新特性
    hooks只能在函数组件使用
    hooks和现有代码可以同时工资,可以渐进式地使用
    hooks带来了更强大的逻辑复用

    useState修改函数组件状态

    格式一:

    const res = useState(100)
    const [count,setCount] = res
    
    • 1
    • 2

    格式二:

      const [content,setContent] = useState(()=>{
          return 'abc'
      })
    
    • 1
    • 2
    • 3

    useState函数中:可以计算、localStorage拿值

    注意:
    1.只能出现在函数组件内部
    2.useState不能使用if或for中,如果存在无法知道调用的是哪个hooks

    userffect 理解副作用

    函数式组件中
    主作用:根据数据渲染ui
    副作用:数据请求,手动修改DOM、localstorage操作等

    userEffect挂载和更新时会执行

    userEffect(()=>{
        //事件绑定,请求数据
    
    },[])
    
    • 1
    • 2
    • 3
    • 4
    //n改变执行
    userEffect(()=>{
    
    },[n])
    // 参数为空,只执行一次
    userEffect(()=>{
    
    },[])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    n变化执行(依赖项变),依赖项可以多个

    副作用函数 返回值

    返回值可以清理副作用
    清理函数会在组件卸载以及下一次副作用函数调用前执行

     useEffect(()=>{
          setInterval(()=>{
            setCount((count)=>count - 1)
          },1000)
          return ()=>{
            console.log('清理副作用')
          }
      },[])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    useEffect可以模拟函数钩子

    自定Hooks

    逻辑复用
    自定义Hooks 名字用use开头
    只能在函数组件或自定义hooks中调用

    useRef

    使用场景:在React中进行DOM操作时,用来获取DOM
    作用:
    1.返回一个带有current属性的可变对象,通过该对象可以进行DOM操作
    2.多次渲染中共享数据

      import { useEffect, useRef, useState } from 'react'
      const refTimerId = useRef(null)
      
      //部分代码
      const hClick = () =>{console.log(refTxt.current.value)}
       <input ref={refTxt} />
       <button onClick={this.hClick}>点击获取input中的值</button>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    useContext 全局状态

    跨组件通讯

    // index.js 根组件
    import React, { useState,createContext } from 'react'
    import Father from './Father'
    
    export  const Context = createContext()
    export default function Index() {
        const [color,setColor] = useState('red')
        return (
            <Context.Provider value={color}>
                 <div style={{border:'1px solid #ccc',margin:40}} >
                根组件:
                color:{color}
                <button onClick={()=>{
                    setColor('green')
                }}>
                    改成green
                </button>
                <Father></Father>
                </div>
            </Context.Provider>
       
      )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    //Father组件
    import React from 'react'
    import Son from './Son'
    
    export default function Father() {
      return (
        <div style={{border:'1px solid #ccc',margin:10}}>
          父组件
          <Son></Son>
        </div>
      )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    import React,{useContext} from 'react'
    import {Context} from './index'
    function Son() {
      const res = useContext(Context)
      return (
        <div style={{border:'1px solid #ccc',margin:10}}>
          子组件:color:{res}
        </div>
      )
    }
    
    export default Son
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Redux

    多组件共享数据
    安装redux

    npm i redux
    
    • 1

    redux核心概念:

    1.store
    2.action
    3.reducer

    react-redux

    npm i react-redux
    
    • 1
    reducer分离

    combineReducers 合并reducer

    纯函数

    相同的输入总是得到相同的结果
    reducer也是纯函数

    拓展优化 action-creator
    优化 action-type

    redux-中间件-redux-thunk

    支持dispatch函数格式

    npm i redux-thunk
    
    • 1

    redux-中间件-redux-logger

    npm i redux-logger
    
    • 1

    redux调试工具

    未完,持续更新…

  • 相关阅读:
    ROS中Rviz实时路径可视化的高效性能优化技巧
    DHCP服务详解
    java-net-php-python-ssmKTV点歌系统查重PPT计算机毕业设计程序
    【备忘录】修复docker环境下的nacos安全漏洞:身份认证绕过漏洞
    AppCube视角浅析: 艾瑞咨询《2022年中国低代码行业研究报告》
    数据挖掘实战(4)——聚类(Kmeans、MiniBatchKmeans、DBSCAN、AgglomerativeClustering、MeanShift)
    dubbo 知识总结 dubbo配置参考
    Chrome 跨域问题CORS 分析
    Fastjson漏洞+复现
    11【门面设计模式】
  • 原文地址:https://blog.csdn.net/qq_38367703/article/details/126715716