React 基础整理

152 阅读5分钟

1. React特点

   视图层框架  组件系统   单向数据流   前后端分离

2. React Filber

    分片,把每一个耗时长的任务分成很多小片,每一小片的运行时间很短.

3. Component

    任何元素都可以看作一个组件
  

4. React 脚手架

    create-react-app   底层Webpack

5. create-react-app的使用

    1.全局安装  cnpm i create-react-app -g
    2.创建脚手架项目  npx create-react-app demo
    3.启动项目  yarn start
    4.webpack配置文件  node_module/react-script/config/webpack.config.js
    5.抽离webpack配置文件  yarn eject

6.create-react-app 配置less模块化

https://blog.csdn.net/harry_yaya/article/details/108453744

7.React的两种数据形式

   state [状态]    props[属性]
   
   1.props  
     1>类组件
         1.外部传入    this.props接受
         2.内部定义    static defaultProps={}
         
     2>函数组件
         1.外部传入    {aa} 在参数中解构 
         
     3>props校验    prop-types   校验外部传入
         Hello.propTypes = {
             aa:PropTypes.string
         }
     
   2.state  [自己定义,自己修改]
       1>类组件
           1.state = {count:0}
           2.constructor(props){
               super(props)   //this.props = props
               this.state = {count:0}
           }
           
       2>函数组件
           1.useState [Hooks]
               const [count] = useState(0)
           

8.事件绑定形式

    1.类组件
        onClick={this.handle}  const handle = ()=>{console.log(1)}
        
    2.函数组件
        onClick={handle} const handle = ()=>{console.log(1)}
        
    3.函数传参需要使用箭头函数包裹
         onClick={ () => { handle(val) } } const handle = ()=>{console.log(1)}

9.setState修改状态

    1.类组件
       this.setState({
           count:this.count++
       }) 
       
       this.setState(({count}))=>{
           return {
               count:count
           }
       })
       
       setState两个回调函数,第一个回调函数修改state数据,第二个回调函数可以拿到更新后得state值
    
    
    2.函数组件
        const [ count,setCount ] = useState(0)
        handle = ()=>{
            setCount(1)     //赋值一次
        }
        
        handle = ()=>{
            setCount( preCount=>preCount+1 )  //回调函数
        }
        
    短时间,多次执行多个setState,React会进行合并  {合并列  Object.assign  队列}

10.数据渲染

    1.数据展示  {}  dangerousSetInnerHTML = {{__html:xml}}
    2.条件渲染  { flag ? '真' : '假' }  //可以是标签
    3.列表渲染  <ul>{ arr.map( item => <li key={index} >{item}</li>  )}</ul>  需要有Key值

11.组件通信

  1.父子组件    【父组件定义状态,子组件接受】
  2.子父组件    【子组件定义状态,父组件给子组件船事件,子组件调用事件传参,父组件接收参数】
  3.非父子组件   类组件【1.父组件定义方法传给其中一个组件2.其他一个组件使用ref ref={ el => this.hello = el }  this.hello.方法名】
  4.跨组件      【createContext 创建上下文 moneyContext.Provider  value={money}   孙子组件:static contextType = moneyContext  this.context】

12.生命周期(类组件) 父组件状态更改会引起子组件的重新渲染render

    1.初始化阶段
        1constructor           【主线程结束之后执行,异步执行】
            1.通过super将绑定在组件身上的props赋值给this.props
            2.定义state
            3.普通函数绑定this
            
        2》componentWillMount    【新版本舍弃】
            1.组件即将挂载
            2.拿到state,没有真实DOM
            
        3》render                【底层 React.createElement】
            1.解析this.props / this.state 
            2.将jsx元素渲染为vdom对象原型,生成虚拟DOM
            3.不可以使用setState()  【单线程,解析同时不可以展示】
                     
        4》componentDidMount     【】
            1.组件挂载结束
            2.数据请求,数据修改
            3.拿到真实DOM 第三方化组件实例
         
    2.更新阶段                    【setState/forceUpdate】
        1》componentWillReceiveProps(nextProps) 【只针对props,state没有这个钩子函数】     
            1.获取最新的属性
            2.用于判断组件当前属性是否改变
            
        2》shouldComponentUpdate(nextProps,nextState) 
            1.组件是否更新
            2.写上必须要有返回值,布尔值
            3.性能优化
            4.props拿到的是不一样的值,state拿到的都是最新的值
            
        3》componentWillUpdate    【新版本舍弃】
            1.组件即将更新
            
        4》render
        
        5》componentDidUpdate
            1.组件更新结束
            2.真实DOM生成,获取数据,更新数据
        
    3.销毁阶段
        1》componentWillUnmount 
            1.清除无用的实例和事件
            2.定时器,第三方实例
        
    4.错误捕获阶段
        1》componentDidCatch
            1.捕获子组件throw出来的错误

13.高阶组件

    1.复用组件逻辑,一种设计模式,
    2.HOCHigh Order Component3.一个封装函数,接受一个组件作为参数
    4.返回值是一个类组件
    export function HocComp(Comp){
        return class _ extends Component{
        
            // 复用逻辑
            
            render(){
                return <Comp/>
            }
        }
    }
    
    const withTab = HocComp(Tab)

14.受控组件 / 非受控组件

    表单元素的value值受组件的state控制,这个表单元素称为受控组件
    
    
    handle = e => {
        this.setState({
            val:e.target.value
        })
    }
    
    <input value={this.val} onChange={this.handle} />
    
    
    非受控组件
    <input defaultValue={this.val} />

15.craco.config.js配置

    1》反向代理
        devServer:{
            proxy:{
                '/api':{
                    target:'https://m.moayan.com',
                    changeOrigin:true  //使用当前服务器代理目标源
                    pathRewrite:{
                        '^/api':''   //后端没有统一词,需要进行路径的重写
                    }
                }
            }
        }
    
    2》webpack:{
        alias:{
            '@':path.join(__dirname,'./src')
        }
    }
        

16.路由

    1.SPA 单页面的切换
    2.react-router   react-router-dom
    
    
    1》确定路由模式
      HashRouter / BrowserRouter  
      
      import {BrowserRouter as Router} from 'react-router-dom'
      <Router>
          <App/>
      </Router>
      
      路由配置数组  component:lazy(()=>import('@/page/home'))  //路由懒加载
      
      路由配置文件
      <Suspense fallback={<div>加载中...</div>}>   //转场组件
       <Switch>   //只显示一个组件
         <Redirect from='/' to='/home' exact />   //重定向组件,exact表示路由路径完全匹配
             < routes.map( (item,index) => <Route key={index} path={item.path} component={item.component} /> )>
       </Switch>
      </Suspense>
      
      
    2》导航
        <NavLink to='/home' activeClassName='active'> 首页 </NavLink>   //待带激活
        <Link to='/user'> 个人中心 </Link>    //只是跳转
        
        编程式导航
            history location match
            history (push,go,goBack)
            location (pathname,search,state)
            
    3》动态路由
            <Link 
                to={{
                    pathname='/list/1'
                    search:?a=1&b=2&c=3    //查询参数
                    state:{ 
                        title:'商品1'      //路由元信息
                    }
                 }}
             </Link>
             
             处理查找字符串:qs.parse(search.slice(1))
             
    4》路由拦截  判断有无token,有则显示路由,没有跳转登录页面
    6》路由鉴权  获取用户身份,在路由中添加自定义选项,
    5》路由监听  componentWillReceiveProps

17. Hooks (函数组件) loadsh

    1. useState             【定义state,修改state】
        1》复杂数据类型不能直接修改
        
    2. useEffect            【实现类组件的componentDidMount/componentDIdUpdate/componentWillUnmout功能】
       1》第一个参数回调函数,
       2》第二个参数空数组,执行一次
       3》第二个参数有值,表示监听这个值得变化,才会触发回调函数
       4》useEffect可以写多个
       5》第二个参数可以是多个state
       
    3. useContext           【实现跨组件通信】
   
    4. useRef               【用于绑定元素/组件】
        1》元素的获取
            const pEle = useRef(null)
            function getP (){
                console.log(pEle.current)
            }
            <p ref={pEle} ></p>
        
        2》组件的获取
            ref不能绑定函数组件
            需要使用React.forWardRef(Hello)
            使用useImperativeHandle抓取子组件的方法,第一个参数ref,第二个参数回调函数
            useImperativeHandle(ref,()=>({
                a:1,
                add(){
                    setCount(preCount=>preCount+1)
                }
            }))
    
    5. useImperativeHandle  【搭配useRef使用,获取函数组件中定义的方法】
    
    6. useMemo              【函数组件优化】
        const memoList = useMemo(()=>renderList(),[list])
    
    7. useCallback          【函数组件优化】

18.自定义Hook

   就是一个函数
   ()可以接受数据
   export function useStatus(data){
       if(data.a){
           //做操作
       }
       if(data.b){
           //做操作
       }
   }
   
   不可以嵌套Hook