当前位置: 首页 > news >正文

React 学习笔记总结(二)

文章目录

  • 1. React 之 props的使用
  • 2. React 之 对props进行限制
  • 3. React 之 props只读 (知道修改在这是什么效果!)
  • 4. React 之 props简写方式
  • 5. 类式组件中的构造器 与 props的注意事项
  • 6. 函数式组件 使用props
  • 7. 类式组件字符串形式的refs属性
  • 8. React 之 回调形式ref
  • 9. jsx的注释形式
  • 9. React 之 回调形式ref的 调用次数问题
  • 9. createRef API的使用
  • 10. React的 事件处理的 过程
  • 11. 勿过度使用Refs
  • 12. React 之 非受控组件
  • 13. React 之 受控组件
  • 14. 高阶函数 和 柯里化
    • 14.1 高阶函数 和 柯里化的概念
    • 14.2 react的代码简化

1. React 之 props的使用


在组件上面,声明属性,会直接放到实例对象的props属性中。

这样外部组件传递过来的值,就可以直接调用了。

<script type="text/babel">
    // 创建组件
    class Person extends React.Component{
        render() {
            console.log(this)
            let {name,age,sex} = this.props
            return (
                <div>
                    <ul>
                        <li>姓名:{name}</li>
                        <li>性别:{age}</li>
                        <li>年龄:{sex}</li>
                    </ul>
                </div>
            );
        }
    }
    // 渲染组件到页面
    ReactDOM.render(<Person name="tom" age="18" sex="男"/>,document.getElementById('test'))
</script>

** …xxx 叫做 展开运算符:**

  • 注意:展开运算符,不能展开对象!
    在这里插入图片描述

对于对象,扩展运算符可以用来做浅复制、合并的操作。
在这里插入图片描述


在React中就可以使用这种方式,因为babel和react是能够进行加工操作的!

在这里插入图片描述


props的写法有以下两种:(知道就好,第一种已经弃用。)

  • 注意:Person.propTypes 与 PropTypes.string 的 propsTypes大小写。容易写错!
    在这里插入图片描述

2. React 之 对props进行限制


对组件的props进行限制,就需要到了prop-types.js功能包。

引入prop-types.js:用于对组件标签属性进行限制。

  • 第一步:引入prop-types.js。
  • 第二步:配置Person.propTypes = {} 定义属性类型、是否必须等。
  • 第三步:配置Person.defaultProps = {} 默认值。
<body>
    <!-- 1. 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 2. 引入react-dom,用于支持react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 3. 引入babel,用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <!-- 4.引入prop-types.js:用于对组件标签属性进行限制 -->
    <script type="text/javascript" src="../js/prop-types.js"></script>

    <script type="text/babel">
        // 创建组件
        class Person extends React.Component{
            render() {
                console.log(this)
                // 调用的时候直接调用props里面的函数。
                this.props.speak()
                let {name,age,sex} = this.props
                return (
                    <div>
                        <ul>
                            <li>姓名:{name}</li>
                            <li>性别:{age + 10}</li>
                            <li>年龄:{sex}</li>
                        </ul>
                    </div>
                );
            }
        }

        // react底层会自动走propTypes,来对Person的props进行限制。
        // 可以设置类型,设置是否必须等等。
        Person.propTypes = {
            name:PropTypes.string.isRequired,
            sex:PropTypes.string,
            age:PropTypes.number,
            speak:PropTypes.func // 如果传入函数就是func
        }
        // 指定默认标签属性值,也就是设置属性默认值。
        Person.defaultProps = {
            sex: '不男不女',
        }

        function speak(){
            console.log('我说话了')
        }

        const p = {name:'老刘',age:18}
        // 渲染组件到页面
        ReactDOM.render(<Person {...p} speak={speak}/>,document.getElementById('test'))
    </script>
</body>

3. React 之 props只读 (知道修改在这是什么效果!)


React的props是只读的。

在这里插入图片描述

搞懂:修改什么意思,可以理解为重新赋值的意思。就是地址发生改变。
在这里插入图片描述

4. React 之 props简写方式


其实下面的代码就是往Person里面添加属性,那么可以直接简写到Person类中:

// react底层会自动走propTypes,来对Person的props进行限制。
// 可以设置类型,设置是否必须等等。
Person.propTypes = {
    name:PropTypes.string.isRequired,
    sex:PropTypes.string,
    age:PropTypes.number,
    speak:PropTypes.func // 如果传入函数就是func
}
// 指定默认标签属性值,也就是设置属性默认值。
Person.defaultProps = {
    sex: '不男不女',
}

简写形式如下:

class Person extends React.Component{
	// 定义props属性
    static propTypes = {
        name:PropTypes.string.isRequired,
        sex:PropTypes.string,
        age:PropTypes.number,
        speak:PropTypes.func // 如果传入函数就是func
    }
	// 定义props默认值
    static defaultProps = {
        sex: '不男不女',
    }

    render() {
        // 调用的时候直接调用props里面的函数。
        this.props.speak()
        let {name,age,sex} = this.props
        return (
            <div>
                <ul>
                    <li>姓名:{name}</li>
                    <li>性别:{age + 10}</li>
                    <li>年龄:{sex}</li>
                </ul>
            </div>
        );
    }
}

5. 类式组件中的构造器 与 props的注意事项


类式组件构造器,在react中,仅用到以下两种情况:

  • 通过给this.state 赋值对象来初始化内部state。
  • 为事件处理函数绑定实例。

注意点:

  • 如果,不需要初始化constructor构造器,无影响。

  • 如果,需要初始化了constructor构造器并且希望在构造器中通过this访问props,则必须要接受props和实现super(props),不然拿不到props!

几乎开发当中不会使用构造器的!

6. 函数式组件 使用props


三大属性:state,props,refs。

函数式组件只能使用props,其他两个都不能使用。

props作为参数传递,并且限制props属性直接在外面定义就可以。

<script type="text/babel">
    function Person(props){
        const {name,sex,age} = props
        return (
            <ul>
                <li>姓名:{name}</li>
                <li>性别:{sex}</li>
                <li>年龄:{age + 1}</li>
            </ul>
        )
    }
    Person.propType = {
        name:PropTypes.string.isRequired,
        sex:PropTypes.string,
        age:PropTypes.number
    }
    Person.defaultProps = {
        sex:'不男不女',
        age:18
    }
    ReactDOM.render(<Person name="zhangsan" age={1}/>,document.getElementById('test'))
</script>

7. 类式组件字符串形式的refs属性


类式组件refs属性存折对应ref标识,与id作用差不多。
在这里插入图片描述

通过refs属性就可以操作对应dom节点:

<script type="text/babel">
    class Demo extends React.Component {

        // 展示左侧输入框的数据
        showData = ()=>{
            const {input1} = this.refs
            alert(input1.value)
        }
        // 展示右侧输入框的数据
        showDate2 = () => {
            const {input2} = this.refs
            alert(input2.value)
        }

        render() {
            return (
                <div>
                    <input ref="input1" type="text" placeholder="点击按钮提示数据"/>
                    <button ref="button1" onClick={this.showData}>点我提示左侧的数据</button> &nbsp;
                    <input ref="input2" onBlur={this.showDate2} type="text" placeholder="失去焦点提示数据"/>
                </div>
            );
        }
        
    }
    // 渲染组件到页面
    ReactDOM.render(<Demo/>,document.getElementById('test'))
</script>

官方对字符串形式的refs给出的解释:

  • 存在一些效率问题。
    在这里插入图片描述

8. React 之 回调形式ref


通过回调函数的形式来实现:

// 通过回调函数的形式来给this赋值。
render() {
    return (
        <div>
            <input ref={c=>this.input1 = c} type="text" placeholder="点击按钮提示数据"/>
        </div>
    );
}

案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsx语法规则</title>
</head>
<body>
    <!-- 准备好一个容器 -->
    <div id="test"></div>

    <!-- 1. 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 2. 引入react-dom,用于支持react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 3. 引入babel,用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <!-- 4.引入prop-types.js:用于对组件标签属性进行限制 -->
    <script type="text/javascript" src="../js/prop-types.js"></script>

    <script type="text/babel">
        class Demo extends React.Component {

            // 展示左侧输入框的数据
            showData = ()=>{
                const {input1} = this
                alert(input1.value)
            }
            // 展示右侧输入框的数据
            showDate2 = () => {
                const {input2} = this
                alert(input2.value)
            }

            // 通过回调函数的形式来给this赋值。
            render() {
                return (
                    <div>
                        <input ref={c=>this.input1 = c} type="text" placeholder="点击按钮提示数据"/>
                        <button onClick={this.showData}>点我提示左侧的数据</button> &nbsp;
                        <input onBlur={this.showDate2} ref={c=>this.input2 = c}  type="text" placeholder="失去焦点提示数据"/>
                    </div>
                );
            }

        }
        // 渲染组件到页面
        ReactDOM.render(<Demo/>,document.getElementById('test'))
    </script>
</body>
</html>

9. jsx的注释形式


通过使用{}将其转换为js表达式再通过/**/来注释。

render() {
    return (
        <div>
            <input ref={c=>this.input1 = c} type="text" placeholder="点击按钮提示数据"/>
            {/*<button onClick={this.showData}>点我提示左侧的数据</button> &nbsp;*/}
            <input onBlur={this.showDate2} ref={c=>this.input2 = c}  type="text" placeholder="失去焦点提示数据"/>
        </div>
    );
}

9. React 之 回调形式ref的 调用次数问题


内联函数指的是直接在标签上面定义的函数。
在这里插入图片描述

对于ref的内联函数回调,更新dom会出现的二次调用的情况:

  • 第一次初始化页面的时候,ref里面的回调函数就会被调用一次。
  • 之后,只要类式组件的render函数被调用(更新dom),那么更新中ref里面的函数会调用两次,第一次参数c(currentNode)为null,第二次参数c(currentNode)就会是当前的节点。第一次为null是因为要清空一下。

在这里插入图片描述


上面函数有对应解决办法,可以将函数放到this类实例对象当中,这样就可以直接调用了。不用再写内联函数了。

在这里插入图片描述

两种情况都可以,但是知道两者的区别。

9. createRef API的使用


React.createRef()调用后可以返回一个容器,该容器可以存储被ref所标识的节点。

注意:React.createRef()只能锁定一个节点,专人专用!

class Demo extends React.Component {
    /*
        React.createRef()调用后可以返回一个容器,该容器可以存储被ref所标识的节点,不过它只能锁定一个节点,专人专用!。
     */
    myRef = React.createRef()
    showData = ()=>{
        console.log(this.myRef.current)
    }
    render() {
        return (
            <div>
                <input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>
                <button onClick={this.showData}>点我提示左侧的数据</button>
            </div>
        );
    }
}
// 渲染组件到页面
ReactDOM.render(<Demo/>,document.getElementById('test'))

原理:走到input ref={this.myRef}的时候,检测到是一个通过React.createRef()创建的容器,就会把自身节点存到里面。

目前,推荐官方使用的一种形式。但是很多开发依然用的内联函数。

10. React的 事件处理的 过程


React的是通过onXxx属性指定事件处理函数,注意中间是大小写。

  • React使用的是自定义(合成)事件【为了更好的兼容性】,而不是使用的原生的DOM事件。
  • React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)。
    所谓的事件委托将事件像冒泡一样委托给了最外层的元素。

11. 勿过度使用Refs


通过event.target得到发生事件的DOM元素对象:

官方给出一个 勿过度使用Refs ,其实很多时候可以直接使用event.target来获取当前节点。

在这里插入图片描述

12. React 之 非受控组件


非受控组件就是现用现取:

  • 就像下面input输入,点击登录才会走react的onSubmit事件。
<script type="text/babel">
    // 创建组件
    class Login extends React.Component{

        handlerSubmit = (event)=>{
            const {username,password} = this
            alert(`${username.value},${password.value}`)
            // 阻止form表单提交
            event.preventDefault() //组织form表单默认事件。
        }

        render() {
            return (
                <div>
                    <form action="http://www.itholmes.com" onSubmit={this.handlerSubmit}>
                        用户名:<input ref={c => this.username = c} type="text" name="username"/>
                        密码:<input ref={c => this.password = c} type="password" name="password"/>
                        <button>登录</button>
                    </form>
                </div>
            );
        }
    }
    // 渲染组件
    ReactDOM.render(<Login/>,document.getElementById('test'))
</script>

13. React 之 受控组件


其实受控组件有点像vue的双向绑定效果,就像下图通过react的onChange事件来绑定到了state状态当中:

在这里插入图片描述

<script type="text/babel">
    // 创建组件
    class Login extends React.Component{

        // 初始化状态
        state = {
            username:'',
            password:''
        }

        saveUsername = (event)=>{
            this.setState({username : this.username.value})
        }

        savePassword = (event)=>{
            this.setState({password:this.password.value})
        }

        handlerSubmit = (event)=>{
            // 阻止form表单提交
            event.preventDefault() //组织form表单默认事件。
            const {username,password} = this.state
            console.log(`${username},${password}`)
        }

        render() {
            return (
                <div>
                    <form action="http://www.itholmes.com" onSubmit={this.handlerSubmit}>
                        用户名:<input onChange={this.saveUsername} ref={c => this.username = c} type="text" name="username"/>
                        密码:<input onChange={this.savePassword} ref={c => this.password = c} type="password" name="password"/>
                        <button>登录</button>
                    </form>
                </div>
            );
        }
    }
    // 渲染组件
    ReactDOM.render(<Login/>,document.getElementById('test'))
</script>

推荐使用受控组件,受控组件很少用到ref属性,而且方便。

14. 高阶函数 和 柯里化

14.1 高阶函数 和 柯里化的概念


在这里插入图片描述

像Promise、setTimeout、arr.map()等等接受的参数都是函数,因此他们都是高阶函数!

在这里插入图片描述
以下的react代码就是通过柯里化的方式实现。


不使用柯里化的实现:
在这里插入图片描述

14.2 react的代码简化


注意:事件下面的两个形式是不同的!

  • 不加括号就是将一个函数给了onChange事件。
  • 加上括号就是将一个函数的返回值给了onChange事件,这是个误区!
    在这里插入图片描述

因为上面的原因,所以往后可以通过return函数的方式来赋予事件,并且简化代码:
在这里插入图片描述

<script type="text/babel">
    // 创建组件
    class Login extends React.Component{

        // 初始化状态
        state = {
            username:'',
            password:''
        }

        // 通过return函数来赋值给onChange事件,
        saveFormData = (dataType)=>{
            console.log(dataType)
            return (event)=>{
                // fixme [dataType] 读取对象dataType的值,对象的基本用法!!
                this.setState({[dataType]:event.target.value})
                console.log('dataType',dataType)
                console.log('value',event.target.value)
            }
        }

        handlerSubmit = (event)=>{
            // 阻止form表单提交
            event.preventDefault() //组织form表单默认事件。
            const {username,password} = this.state
            console.log(`${username},${password}`)
        }

        render() {
            return (
                <div>
                    <form action="http://www.itholmes.com" onSubmit={this.handlerSubmit}>
                        用户名:<input onChange={this.saveFormData('username')} type="text" name="username"/>
                        密码:<input onChange={this.saveFormData('password')} type="password" name="password"/>
                        <button>登录</button>
                    </form>
                </div>
            );
        }
    }
    // 渲染组件
    ReactDOM.render(<Login/>,document.getElementById('test'))
</script>

相关文章:

  • ssh登陆概率性失败,报错:kex_exchange_identification
  • 微服务项目:尚融宝(60)(核心业务流程:个人中心)
  • 【P8179】【EZEC-11】Tyres(背包问题,决策单调性,分治)
  • <Linux复习>权限概念上
  • 嵌入式开发:嵌入式安全的6个要点
  • 第2章 Linux的Shell基础(一)
  • 0926物体检测和数据集
  • 【PAT甲级】1064 Complete Binary Search Tree
  • ASEMI快恢复二极管FR207参数,FR207图片,FR207应用
  • Golang常见面试题及解答
  • 全网最牛的使用python快速搭建接口自动化测试脚本实战总结
  • 湖仓一体电商项目(二十三):离线业务 统计每天用户商品浏览所获积分
  • LeetCode0022.括号生成 Go语言AC笔记
  • 云套件将http协议改为https协议
  • ThingsKit 物联网平台 v1.0.0 Release 版本发布
  • [译]如何构建服务器端web组件,为何要构建?
  • 【前端学习】-粗谈选择器
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • Android框架之Volley
  • Java比较器对数组,集合排序
  • Java反射-动态类加载和重新加载
  • Java-详解HashMap
  • Joomla 2.x, 3.x useful code cheatsheet
  • js 实现textarea输入字数提示
  • oldjun 检测网站的经验
  • oschina
  • quasar-framework cnodejs社区
  • Zepto.js源码学习之二
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 力扣(LeetCode)965
  • 入门级的git使用指北
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 优秀架构师必须掌握的架构思维
  • 浅谈sql中的in与not in,exists与not exists的区别
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #pragma 指令
  • #每日一题合集#牛客JZ23-JZ33
  • #微信小程序:微信小程序常见的配置传值
  • (0)Nginx 功能特性
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (zt)最盛行的警世狂言(爆笑)
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (转载)Google Chrome调试JS
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • **PHP二维数组遍历时同时赋值
  • **python多态
  • .NET 读取 JSON格式的数据
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • .NET开发人员必知的八个网站
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • []error LNK2001: unresolved external symbol _m
  • [100天算法】-每个元音包含偶数次的最长子字符串(day 53)