美文网首页JavaScript 进阶营让前端飞
recompose函数式库 + ( git? ) + ( vo

recompose函数式库 + ( git? ) + ( vo

作者: woow_wu7 | 来源:发表于2018-09-16 20:47 被阅读352次

    (一) recompose 函数式组件,高阶组件库

    (1) withState

    因为函数式组件中没有state,但是更多时候是需要使用state的,所以recompose提供了withState来满足需求

    withState(
      stateName: string,  ----------------------------------- state的名称
      stateUpdaterName: string,   --------------------------- 改变state的函数
      initialState: any | (props: Object) => any ------------ 初始值,任意值或者父组件传的props的函数
    ): HigherOrderComponent
    
    
    
    注意:
    (1) 第三个参数:是函数时,参数是从父组件传过来的props
    
    
    
    实例:
    import React, { Component } from 'react';
    import './App.css';
    import { compose, withState } from 'recompose';  ----------- 引入recompose的两个函数
    const ComponentA = (props) => { ---------------------------- 这里最好写成解构的形式,让参数透明化
      return(
        <div>
          recompose测试
          <br/>
          {props.name}  ---------------------------------------- 通过props,获取到state的name属性的值
        </div>
      );
    }
    export default compose(
      withState('name', 'changeName', 'wang'),  ---------------- 使用withState(名字,函数,初始值)
    )(ComponentA);
    

    (2) withProps

    withProps(
      createProps: (ownerProps: Object) => Object | Object ------ withProps的参数是一个函数或者一个对象
    ): HigherOrderComponent
    
    
    
    注意:
    (1) withProps的参数是一个对象,或者一个函数(返回值是对象)
    (2) 当withProps的参数是一个函数时,函数的参数来自于 withProps 上面的 withProps
    (2) 当withProps的参数是一个函数时,函数的参数是ownerProps一个对象,函数的返回值也是一个对象
    
    
    
    实例:
    import React, { Component } from 'react';
    import './App.css';
    import { withProps, compose, withHandlers, withState } from 'recompose';
    
    const ComponentA = (props) => { ------------------ 这里最好写成解构的形式,让参数透明化
      console.log(props, 'props')
      return(
        <div>
          recompose测试
          <br/>
          <div>语文: {props.chinese}</div>
          <div>数学: {math}</div>
          <div>英语: {props.english}</div>
          <div>总分: {props.total}</div>
        <br/>
        </div>
      );
    }
    
    const math = 100;
    
    const getUserMessage = ({ ----------------------- withProps 对应的函数
      chinese,  ------------------------------------- 参数来自 ( 该withProps ) 上面的 ( withProps )
      english,  ------------------------------------- 参数来自 ( 该withProps ) 上面的 ( withState )
    }) => {  
      return ({
        total: chinese + english + math   ---------------- withProps需要返回一个对象
      })
    }
    
    export default compose(
      withProps({ ---------------------------------------- withProps是一个对象
        chinese:20
      }),
      withState('english', 'changeScore', 80),
      withProps(getUserMessage), ------------------------- withProps是一个函数
    )(ComponentA);
    

    (3) withHanders

    withHandlers(
      handlerCreators: {  ------------------------------------- withHanders接受一个 handlerCreators
        [handlerName: string]: (props: Object) => Function  --------------- 返回一个操作函数
      } |
      handlerCreatorsFactory: (initialProps) => { ------------- withHanders接受一个 工厂函数
        [handlerName: string]: (props: Object) => Function
      }
    ): HigherOrderComponent
    
    
    
    
    注意:
    (1) withHanders接收一组 handler creator 或 工厂函数. 这些函数是高阶函数, 接收一组props,返回操作函数
    (2) 操作函数可能有定义好的参数,比如antd中验证的回调函数,自带的参数,再比如onClick函数的e参数
    
    
    
    
    实例:
    import React, { Component } from 'react';
    import './App.css';
    import { withProps, compose, withHandlers, withState } from 'recompose';
    
    const math = 100;
    
    const ComponentA = (props) => {
      console.log(props, 'props')
      return(
        <div>
          recompose测试
          <br/>
          <div>语文: {props.chinese}</div>
          <div>数学: {math}</div>
          <div>英语: {props.english}</div>
          <div onClick={props.handleChangeScore}>总分: {props.total}</div> ----- 点击执行withHanders
        <br/>
        </div>
      );
    }
    
    const getUserMessage = ({
      chinese,
      english,
    }) => {
      return ({
        total: chinese + english + math
      })
    }
    
    export default compose(
      withProps({
        chinese:20
      }),
      withState('english', 'changeScore', 80),
      withProps(getUserMessage),
      withHandlers({ ------ withhander接受一个高级函数,参数是 props,返回操作函数,操作函数有自己的参数
        handleChangeScore: props => e => { ----------------- 函数名是 handleChangeScore,返回操作函数
          console.log(e.target);
          return props.changeScore(n => n = 20) ------------ changeScore是withState中的函数
        } ------------------------------ changeScore中的参数就是对应的withState中对应的 state
      })
    )(ComponentA);
    

    (4) lifecycle

    生命周期函数
    这是高阶组件版本的React.Component(),支持除了render()之外的所有Component API, render()方式是默认实现的. 任何lifecycle()方法引起的 state改变, 会传递给包装组件

    lifecycle(
      spec: Object,   ----------------------------------- 一个对象
    ): HigherOrderComponent
    
    
    注意:参数是一个对象
    
    
    实例:
    import React, { Component } from 'react';
    import './App.css';
    import { withProps, compose, withHandlers, withState, lifecycle } from 'recompose';
    
    const math = 100;
    
    const ComponentA = (props) => {
      console.log(props, 'props')
      return(
        <div>
          recompose测试
          <br/>
          <div>语文: {props.chinese}</div>
          <div>数学: {math}</div>
          <div>英语: {props.english}</div>
          <div onClick={props.handleChangeScore}>总分: {props.total}</div>
        <br/>
        </div>
      );
    }
    
    const getUserMessage = ({
      chinese,
      english,
    }) => {
      return ({
        total: chinese + english + math
      })
    }
    
    export default compose(
      withProps({
        chinese:20
      }),
      withState('english', 'changeScore', 80),
      withProps(getUserMessage),
      withHandlers({
        handleChangeScore: props => e => {
          console.log(e.target);
          return props.changeScore(n => n = 20)
        }
      }),
      lifecycle({   -------------------------------- 函数式组件的生命周期函数
        componentDidMount(){
          console.log('aaaaaaaaaaaaa')
        }
      })
    )(ComponentA);
    
    

    https://juejin.im/entry/5a28fc076fb9a04511710659
    https://note.pcwu.net/2017/03/11/react-recompose/
    http://functional-programming.cn/t/topic/70










    老是记不住的git,多写几遍

    新建文件夹:mkdir B  
    
    
    新建文件: touch a.txt
    
    
    删除文件:rm a.txt
    
    
    修改文件内容: vim a.txt
    
    
    查看当前路径: pwd
    
    
    把远程某个分支拉取到本地不存在的分支: 
    git checkout -b 本地分支名 origin/远程分支名
    例如: git checkout -b dev origin/dev --------------把远程的dev分支拉取到新建的本地分支dev中
    
    
    git checkout -b dev用该命令新建分支并切换到新分支时,是基于当前分支,即新分支和当前分支内容同步
    
      
      删除本地分支: git branch -d 本地分支名
    强行删除本地分支:git branch -D 本地分支名
    
    
      删除远程分支: git push origin --delete 远程分支名
    
    
      合并分支:git merge dev     ----------------------- 将dev分支合并到当前分支
               git rebase dev   ------------------------ 消除分叉
    
    
      查看所有分支最后一次提交信息: ---------------------- git branch -a -vv
    
    
      查看提交历史: git log --graph --pretty=oneline --abbreve-commit
    
    
      把本地代码上传到github
      (1) 在github上新建项目
      (2) git init,add,commit后使用命令 ----- git remote add origin https://github.com/woow-wu/g.git
      (3) git push -u origin master
    
    
      git pull = git fetch + git merge
      git pull <远程主机名> <远程分支名> : <本地分支名>
      git push <远程主机名> <本地分支名> : <远程分支名>
      git pull origin master:dev ------------ 取回origin主机的master分支,与本地的dev分支合并
    
      git fetch origin master:dev
      git diff dev
      git merge dev
    
    
    
      git pull --rebase
      git pull = git fetch + git merge
      git pull --rebase = git fetch + git rebase
    
    
      查看远程库: git remote
      查看远程库详细信息: git remote -v
    
      
      ( 本地分支关联远程分支 ------------ git branch --set-upstream )
      ( 关联的目的:关联目的是在执行git pull, git push操作时就不需要指定对应的远程分支 !!!!)
      ( git branch --set-upstream-to=origin/dev dev ----- 关联本地dev和远程dev )
      ( git branch --set-upstream-to=origin/remote_branch  your_branch )
      ( upstream是向上,逆流向上的意思 )
    
      
    
    
    
    !!!!!!!!!!!!!!!!!!!!!!! git rebase  !!!!!!!!!!!!!!!!!!!!!!!!!!
    
    
    (1) 合并多个commit为一个完整的commit
    
        git rebase -i  [startpoint]  [endpoint]
    
        或者 git rebase -i HEAD~3      ...
    
        或者 git rebase -i master ----------------------- 从master分支开始
    
        其中-i的意思是--interactive,即弹出交互式的界面让用户编辑完成合并操作
    
        [startpoint]  [endpoint]则指定了一个编辑区间,
        如果不指定[endpoint],则该区间的终点默认是当前分支HEAD所指向的commit
        [ 注意:是前开后闭的区间,即前面的提交取不到,可以使用git rebase -i 分支来实现前闭后闭 ]
    
    
        pick : 保留该commit
        squash:将该commit和前一个commit合并   ----------------- squash挤进挤入的意思
    
    
    
    (2) 将某一段commit粘贴到另一个分支上
    ....
    
    
    
    
    
    
    !!!!!!!!!!!!!!!!!!!!   git push --force   !!!!!!!!!!!!!!!!!!!! 
    
    git push -f origin features/my_branch
    
    只會強制更新 features/my_branch 這個分支的內容,不會影響其它分支。
    
    
    
    
    
    
    !!!!!!!!!!!!!!!!!!!!   git reset   !!!!!!!!!!!!!!!!!!!!
    (1) git reset --mixed
    (2) git reset --hard
    (3) git reset --soft
    
    HEAD   -------------表示当前版本
    HEAD^  -------------表示上一个版本
    HEAD^^ -------------表示上上个版本
    HEAD~100 -----------表示上100个版本
    git reflog ---------记录你的每一次命令,查看命令历史
    
    git reset --mixed commitId
    回退一个版本,且会将暂存区的内容和本地已提交的内容全部恢复到未暂存的状态,不影响原来本地文件
    (未提交的也不受影响) 
    
    git reset –soft HEAD~1 
    回退一个版本,不清空暂存区,将已提交的内容恢复到暂存区,不影响原来本地的文件(未提交的也不受影响) 
    
    git reset --hard commitId
    回退一个版本,清空暂存区,将已提交的内容的版本恢复到本地,本地的文件也将被恢复的版本替换
    
    ``
    
    
    
    !!!!!!!!!!!!!!!!!!!!   git reset HEAD <file>   !!!!!!!!!!!!!!!!!!!!
    git reset HEAD <file>  撤销暂存区的修改
    git reset HEAD <file>可以把暂存区的修改撤销掉(unstage),重新放回工作区
    
    场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file
    
    场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,
    第一步用命令git reset HEAD <file>,就回到了场景1,
    第二步按场景1操作。
    
    
    
    
    
    !!!!!!!!!!!!!!!!!!!!   git checkout -- file   !!!!!!!!!!!!!!!!!!!!
    
    git checkout -- file 撤销工作区的修改
    
    git checkout -- test.txt 将test.txt文件在工作区的修改全部撤销掉,分两种情况:
    (1) test.txt修改后,未放到暂存区,撤销修改后,回到版本库一模一样的状态
    (2) test.txt修改后,添加到了暂存区,再做了些修改,撤销修改后,回到暂存区一样的状态
    总之:就是让这个文件回到最近一次git add 或者 git commit时的状态。
    
    










    void 0

    • void是一元操作符,出现在操作数的左边,操作数可以是任意类型的值
    • void右边的表达式
      可以是带括号形式(例如:void(0))
      也可以是不带括号的形式(例如:void 0)
    • void操作符的作用是返回undefined,右边的操作数正常计算,但无论计算结果是什么,void 都会返回 undefined
    • void操作符总是返回 undefined。
    (一) void操作符的作用:

    (1) 代替undefied
    (2) 填充<a>的href确保点击时不会产生页面跳转; <a href="javascript:void 0">
    (3) 填充<image>的src,确保不会向服务器发出垃圾请求。

    (二) 用 void 0 代替 undefined 的好处:
    1. 防止undefined被重写------------ 非严格模式下可以重写,严格模式不能重写。
    2. 节省字节----------------------------- void 0代替undefined省3个字节。
      https://segmentfault.com/q/1010000007406985
      https://blog.csdn.net/mm19931027/article/details/73136339




    !!10 将其他类型的值,强制转换成布尔值

    !!10 ---------- true

    • 值的类型转换:分为显示转换,和隐式转换
    • 强制转换有三个函数:Number,String,Boolean
      Boolean转换:undefined, null, '', NaN, +0或者-0 -----------------只有这5个是false,其他都是true
      Number(undefined) ----------- NaN
      Number(null)----------------- 0
    var a = '4'-'3';  -------------- 隐式转换,减法运算符两边预期是数值,js会自动将字符串转成数值
    typeof a  // 'number'
    
    
    var a = '111' + 0 ;   //a的结果为数值型;
    var b = 111 + '' ;    //b的结果为字符串类型;
    

    https://blog.csdn.net/qq_31411389/article/details/70332999





    dangerouslySetInnerHTML

    
    <div dangerouslySetInnerHTML={{__html:'<div>顶顶顶顶顶顶顶顶顶顶</div>'}}></div>
    
    




    <React.Fragment>不可见的包裹元素,减少DOM

    • <React.Fragment>主要用来代替顶层用来包裹的div,但是React.Fragment不会生成DOM节点
    import React from 'react';
    
    export default function () {
        return (
            <div>   -------------------------------------- 生成了多余的无用的dom节点,影响效率
                <div>一步 01</div>
                <div>一步 02</div>
                <div>一步 03</div>
                <div>一步 04</div>
            </div>
        );
    }
    
    -------------------------------------------------------------------
    
    
    import React from 'react';
    
    export default function () {
        return (
            <React.Fragment>    --------------------------- 生成不可见的包裹元素,不会生成DOM
                <div>一步 01</div>
                <div>一步 02</div>
                <div>一步 03</div>
                <div>一步 04</div>
            </React.Fragment>
        );
    }
    
    
    -------------------------------------------------------------------
    
    
    
    import React from 'react';
    
    export default function () {
        return [ ------------------------------------------ 数组要写很多逗号
            <div>一步 01</div>,
            <div>一步 02</div>,
            <div>一步 03</div>,
            <div>一步 04</div>
        ];
    }
    
    

    三元表达式的两种嵌套形式

    • 三元表达式是右结合,所有的嵌套形式都满足右结合
    • ( 右结合 ) 的运算符只有3个:一元运算符,三元运算符,赋值运算符
    • 一元运算符有:一元+,一元-,递增,递减,typeof,void,delete等
    • delete是对象的方法: delete score.wang ------------- 删除score对象的wang属性,删除成功返回true,delete只能删除对象本身的属性,不能删除继承属性。删除不存在的属性,也是返回true
    • void一元运算符,右边是操作数,不管右边是值是什么,void都返回undefined,一般用 void 0 代替undefined,可以优化代码。
      void 0 ------------- 返回undefined。
    • typeof返回值类型的字符串形式,一种6种:
      'number','string','boolean','undefined','function','object'
      对象,数组,null返回的都是'object'
      函数返回function
    形式一:
    1 > 3 ? 111 : 3 > 2 ? 222 : 333  -------------------------------- 222, 三元表达式右结合
    相当于 1 > 3 ? 111 : ( 3 > 2 ? 222 : 333 )
    
    
    ----
    
    
    形式二:
    1 > 2 ? 1 ? 22 : 33 : 55  -------------------------------------- 55, 三元表达式右结合
    相当于1 > 2 ? ( 1 ? 22 : 33 ) : 55
    
    




    资源事件

    (1) beforeunload

    beforeunload事件在窗口,文档,各种资源将要卸载前触发

    • 可以用来防止用户不小心卸载资源
    • returnValue属性
    • 如果该事件对象的returnValue属性是一个非空字符串,浏览器就会弹出一个对话框,询问用户是否要卸载该资源
    • 但是,用户指定的字符串可能无法显示,浏览器会展示预定义的字符串。如果用户点击“取消”按钮,资源就不会卸载。
     componentWillMount() {
            window.addEventListener('beforeunload', (e) => {   
                e.returnValue = '你确定要离开吗?';
            })
        }
    
    
      说明:
      window.addEventListener('beforeunload')
      beforeunload事件对象的returnValue非空时,浏览器就会弹出对话框,询问是否要卸载资源;
      但是提示的内容可能不是js指定的项目,而是浏览器预定义的字符串
    

    (2) unload

    unload事件在窗口关闭或者document对象将要卸载时触发。它的触发顺序排在beforeunload、pagehide事件后面。

    • unload事件只在页面没有被浏览器缓存时才会触发,换言之,如果通过按下“前进/后退”导致页面卸载,并不会触发unload事件。

    (3) load 事件

    load事件在页面或某个资源加载成功时触发。

    • 注意,页面或资源从浏览器缓存加载,并不会触发load事件。
    window.addEventListener('load', function(event) {  
      console.log('所有资源都加载完成');
    });
    
    
    说明:
    window.addEventListener('load')在所有资源加载完成时,触发
    
    • error事件是在页面或资源加载失败时触发。abort事件在用户取消加载时触发。


    数组去重总结

    方法1: 循环数组,如果新数组中没有该值,就push进新数组
    
     const oldArray = [1,2,3,3,3,3,4,4,5,6,7];
    
     const newArray = [];
    
     oldArray.forEach((item, index) => {
         if (newArray.indexOf(item) === -1) {  // 如果新数组中没有该值,就push进新数组
              newArray.push(item)
          }
     })
    
    
    方法2: 先数组排序,排序后,重复的值必相邻,相邻的两个值不相等,就push进新数组
        componentDidMount() {
            const oldArray = [8,2,1,3,3,3,3,4,4,5,6,7];
            oldArray.sort((a,b) => a-b);      // 排序后重复的元素必相邻, sort方法改变原数组
            const newArray = [oldArray[0]];  // 取数组中的第一个值作为第一个元素
            oldArray.forEach((item, index) => {
                if(oldArray[index] !== newArray[newArray.length-1]) { 
                    // 数组中每一个值和新数组中的最后一个值做对比,不相等就push进数组
                    newArray.push(oldArray[index])
                }
            });
        }
    
    方法3: set,展开运算符,Array.from
      componentDidMount() {
            const oldArray = [8,2,1,3,3,3,3,4,4,5,6,7];
            const aaaa = [...new Set(oldArray)];
            const bbbb = Array.from(new Set(oldArray))
            console.log(aaaa,bbbb)
        }
    


    Form.create() 和 getFieldDecorator 和 resetFields()

    • antd中的form通过 Form.create()包装后的 getFieldDecorator 中的 input,select等,不能再设置value值,但是可以通过 this.props.form.resetFields()来重新刷新form表单的值

    相关文章

      网友评论

        本文标题:recompose函数式库 + ( git? ) + ( vo

        本文链接:https://www.haomeiwen.com/subject/oiwpiftx.html