验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

JavaScript中React面向组件编程实例代码分析

阅读:621 来源:乙速云 作者:代码code

JavaScript中React面向组件编程实例代码分析

一、受控组件与非受控组件

表单的组件分类:

  1. 受控组件

  2. 非受控组件

多数情况下,推荐使用受控组件实现表单。在受控组件中,表单数据由组件控制。
另外一种是非受控组件,这种方式下表单组件由DOM自身控制。

 1. 受控组件

  1. 受控组件通过 props 获取其当前值,并通过回调函数(比如 onChange )通知变化

  2. 表单状态发生变化时,都会通知 React,将状态交给 React 进行处理,比如可以使用 useState 存储

  3. 受控组件中,组件渲染出的状态与它的 value 或 checked 属性相对应

  4. 受控组件会更新 state 的流程

class Login extends React.Component {
    // 初始化状态
    state = {
        username:'', // 用户名
        password:'', // 密码
    }
    // 保存用户名到状态中
    saveUsername=(event)=>{
        this.setState({username:event.target.value})
    }
    // 保存密码到状态中
    savePassword=(event)=>{
        this.setState({password:event.target.value})
    }
    // 表单提交的回调
    handleSubmit=(event)=>{
        event.preventDefault(); // 阻止默认事件
        
        let {username,password} = this.state
        alert(`你输入的用户名是${username},密码是${password}`)
    }
    render(){
        return(
            
                                     用户名:                         密码:                     登录                                
        )     } }

2. 非受控组件

非受控组件将数据存储在 DOM 中,而不是组件内,这比较类似于传统的 HTML 表单元素。

  1. 非受控组件的值不受组件自身的 state 和 props 控制

  2. 非受控组件使用 ref 从 DOM 中获取元素数据

class Login extends React.Component {
    handleSubmit=(event)=>{
        // console.log(e>=event)
        event.preventDefault(); // 阻止默认事件
        
        let {username,password} = this
        alert(`你输入的用户名是${username.value},密码是${password.value}`)
    }
    render(){
        return(
            
                                     用户名:this.username = c} name="username" />                         密码:this.password = c} name="password" />                     登录                                
        )     } }

 3. 效果展示

JavaScript中React面向组件编程实例代码分析

4. 总结:

  1. React 中的组件分为受控组件和非受控组件

  2. 受控组件的两个要点:

  • 组件的 value 属性与 React 中的状态绑定

  • 组件内声明了 onChange 事件处理 value 的变化

  • 非受控组件更像是传统的 HTML 表单元素,数据存储在 DOM 中,而不是组件内部,获取数据的方式是通过 ref 引用

  • 一些建议:

    • 尽可能使用受控组件

    • 受控组件是将状态交由 React 处理,可以是任何元素,不局限于表单元素

    • 对于有大量表单元素的页面,使用受控组件会使程序变得繁琐难控,此时使用非受控组件更为明智

    • 在受控组件中,数据流是单向的( state 是变化来源),因此在改变 state 时都应该使用 setState ,而不要强制赋值

    • Refs 不能用于函数式组件,因为函数式组件没有实例

    • 在函数式组件内部,是可以使用 Refs 的

     二、组件的生命周期

    所谓的React生命周期,就是指组件从被创建出来,到被使用,最后被销毁的这么一个过程;
    而在这个过程中,React提供了我们会自动执行的不同的钩子函数,我们称之为生命周期函数;

    组件的生命周期大致分为三个阶段:组件挂载阶段,组件更新阶段,组件销毁卸载阶段

    react在版本16.3前后存在两套生命周期,16.3之前为旧版,之后则是新版,虽有新旧之分,但主体上大同小异。

     1. 对生命周期的理解

    1. 组件从创建到死亡它会经历一些特定的阶段。

    2. React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。

    3. 我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作。

     2. 生命周期的三个阶段(旧)

    JavaScript中React面向组件编程实例代码分析

    1. 初始化阶段: 由ReactDOM.render()触发—初次渲染

      1. constructor()

      2. componentWillMount()

      3. render()

      4. componentDidMount()

    2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发

      1. shouldComponentUpdate()

      2. componentWillUpdate()

      3. render()

      4. componentDidUpdate()

    3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发

      1. componentWillUnmount()

    
    
    
        
        
        
        生命周期旧
    
    
        
        
                                               class Count extends React.Component {             state = {                 count:0             }             add = ()=>{                 // 获取原状态                 let {count} = this.state                 // 更新状态                 this.setState({count:count+1})             }             death = ()=>{                 ReactDOM.unmountComponentAtNode(document.getElementById('test'))             }             force = ()=>{                 this.forceUpdate() // 强制更新             }             // 数据更新的 ‘阀门~'             shouldComponentUpdate() {                  console.log("Count --- shouldComponentUpdate");                 return true // 这里必须有返回4值,其次返回值默认是true             }             // 组件将要更新的钩子             componentWillUpdate() {                 console.log("Count ---- componentWillUpdate");             }             // 组件更新完成的钩子             componentDidUpdate() {                  console.log("Count ---- componentDidUpdate");             }              render(){                 console.log("render");                 let {count} = this.state                 return(                     
                            

    当前求和为:{count}

                            点我+1                         卸载组件                         不更改任何状态中的数据,强制更新                     
                    )             }         }         // 父组件         class A extends React.Component {             state = {carName:'小三轮'}             changeCar = ()=>{                 this.setState({carName:"宾利"})             }             render(){                 console.log('A ---- render');                 return(                     
                            
    我是A组件
                            换车                                              
                    )             }         }         // 子组件         class B extends A {             // 组件将要接收新的props的钩子             componentWillReceiveProps(){                 console.log('B ---- componentWillReceiveProps');             }             // 数据更新的 ‘阀门~'             shouldComponentUpdate() {                  console.log("B --- shouldComponentUpdate");                 return true // 这里必须有返回4值,其次返回值默认是true             }             // 组件将要更新的钩子             componentWillUpdate() {                 console.log("B ---- componentWillUpdate");             }             // 组件更新完成的钩子             componentDidUpdate() {                  console.log("B ---- componentDidUpdate");             }              render(){                 console.log('B ---- render');                 return(                     
                            我是B组件,接收到的车是:{this.props.carName}                     
                    )             }         }         ReactDOM.render(,document.getElementById('test'))     

    3. 生命周期的三个阶段(新)

    JavaScript中React面向组件编程实例代码分析

    1. 初始化阶段: 由ReactDOM.render()触发—初次渲染

      1. constructor()

      2. getDerivedStateFromProps

      3. render()

      4. componentDidMount()

    2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发

      1. getDerivedStateFromProps

      2. shouldComponentUpdate()

      3. render()

      4. getSnapshotBeforeUpdate

      5. componentDidUpdate()

    3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发

      1. componentWillUnmount()

    
    
    
        
        
        
        生命周期新
    
    
        
        
                                               class Count extends React.Component {             state = {                 count:0             }             add = ()=>{                 // 获取原状态                 let {count} = this.state                 // 更新状态                 this.setState({count:count+1})             }             death = ()=>{                 ReactDOM.unmountComponentAtNode(document.getElementById('test'))             }             force = ()=>{                 this.forceUpdate() // 强制更新             }             // 数据更新的 ‘阀门~'             shouldComponentUpdate() {                  console.log("Count --- shouldComponentUpdate");                 return true // 这里必须有返回4值,其次返回值默认是true             }             // 组件将要更新的钩子             componentWillUpdate() {                 console.log("Count ---- componentWillUpdate");             }             // 组件更新完成的钩子             componentDidUpdate() {                  console.log("Count ---- componentDidUpdate");             }              render(){                 console.log("render");                 let {count} = this.state                 return(                     
                            

    当前求和为:{count}

                            点我+1                         卸载组件                         不更改任何状态中的数据,强制更新                     
                    )             }         }         // 父组件         class A extends React.Component {             state = {carName:'小三轮'}                          constructor(props) {                 state             }             changeCar = ()=>{                 this.setState({carName:"宾利"})             }             static getDerivedStateFromProps(props, state) {                 // 这里必须要一个返回值 ==> state or null                 // 这里的state会覆盖掉原本的状态,并且后续也无法修改                 // 能将外部的接收的props 赋值给组件自身的 state                 // 如果你希望自身的state一直,全部依赖于外部的props,那么可以使用这个生命周期函数                 return {carName:"QQ"}             }             // 获取护具更新前的快照,能拿到旧的props和state             // 必须有返回值             getSnapshotBeforeUpdate = (prevProps, prevState) => {             }             render(){                 console.log('A ---- render');                 return(                     
                            
    我是A组件
                            换车                                              
                    )             }         }         // 子组件         class B extends A {             // 组件将要接收新的props的钩子             UNSAFE_componentWillReceiveProps(){                 console.log('B ---- componentWillReceiveProps');             }             // 数据更新的 ‘阀门~'             shouldComponentUpdate() {                  console.log("B --- shouldComponentUpdate");                 return true // 这里必须有返回4值,其次返回值默认是true             }             // 将要挂载时             UNSAFE_componentWillMount() {                 console.log("Count --- componentWillUnMount");             }             // 组件将要更新的钩子             UNSAFE_componentWillUpdate() {                 console.log("B ---- componentWillUpdate");             }             // 组件更新完成的钩子             componentDidUpdate() {                  console.log("B ---- componentDidUpdate");             }              render(){                 console.log('B ---- render');                 return(                     
                            我是B组件,接收到的车是:{this.props.carName}                     
                    )             }         }         ReactDOM.render(,document.getElementById('test'))     

    4. 新旧生命周期的区别

    1. 新生命周期中去掉了三个 will 钩子,分别为 componentWillMountcomponentWillReceivePropscomponentWillUpdate

    2. 新生命周期中新增了两个钩子,分别为 getDerivedStateFromProps(从 props 中得到衍生的 state )和 getSnapshotBeforeUpdate

    5. 重要的勾子

    1. render:初始化渲染或更新渲染调用

    2. componentDidMount:开启监听, 发送ajax请求

    3. componentWillUnmount:做一些收尾工作, 如: 清理定时器

    6. 即将废弃的勾子

    1. componentWillMount

    2. componentWillReceiveProps

    3. componentWillUpdate

    警告:

    现在使用会出现警告,下一个大版本需要加上 UNSAFE_ 前缀才能使用,以后可能会被彻底废弃,不建议使用。

    三、高阶函数和函数柯里化的理解

    1. 高阶函数

    如果一个函数符合下面2个规范中的任何一个,那么它就属于一个高阶函数

    1. 若A函数,接收的参数是一个函数,那么A就可以称为高阶函数

    2. 若A函数,它的返回值依然是一个函数,那么A就可以称为高阶函数

     常见的高阶函数:Promise,setTimeout,arr.map(数组方法)

    2. 函数的柯里化

    通过函数继续调用,返回值为函数的方式,实现多次接受参数,最后统一处理的函数编码形式

    function sum(a){
        return (b)=>{
            return (c)=>{
                return a + b + c
            }
        }
    }
    const result = sum(1)(2)(3)
    console.log(result);

    3. 使用函数柯里化代码示例

    class Login extends React.Component {
        // 初始化状态
        state = {
            username:'', // 用户名
            password:'', // 密码
        }
        // 保存表单数据到状态中
        saveFormDate=(dataType,event)=>{ // 标识当前标签
            this.setState({[dataType]:event.target.value})
        }
        // 表单提交的回调
        handleSubmit=(event)=>{
            event.preventDefault(); // 阻止默认事件
            
            let {username,password} = this.state
            alert(`你输入的用户名是${username},密码是${password}`)
        }
        render(){
            return(
                
                                         用户名:this.saveFormDate('username',event)} name="username" />                         密码:this.saveFormDate('password',event)} name="password" />                     登录                                
            )     } }

    4. 不用函数柯里化代码示例

    class Login extends React.Component {
        // 初始化状态
        state = {
            username:'', // 用户名
            password:'', // 密码
        }
        // 保存表单数据到状态中
        saveFormDate=(dataType)=>{ // 标识当前标签
            return (event)=>{ // 这里的回调谁执行? input标签的 onChange事件
                this.setState({[dataType]:event.target.value})
            }
        }
        // 表单提交的回调
        handleSubmit=(event)=>{
            event.preventDefault(); // 阻止默认事件
            
            let {username,password} = this.state
            alert(`你输入的用户名是${username},密码是${password}`)
        }
        render(){
            return(
                
                                         用户名:                         密码:                     登录                                
            )     } }
    分享到:
    *特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
    相关文章
    {{ v.title }}
    {{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
    你可能感兴趣
    推荐阅读 更多>