React有状态组件以及事件处理的相关(案例说明,一看就会)

简介: 今天给大家带来React入门——有状态组件和事件处理。

前言

上篇文章主要讲了JSX语法入门和无状态组件的传值,内容还是比较简单的,今天给大家带来React入门第三弹——有状态组件和事件处理。

组件的分类

==在React中,组件分为函数组件和class组件,也就是无状态组件和有状态组件。==

  • 函数式组件(无状态组件)
    直接定义函数的形式,不存在state,只会有props,它没有生命周期函数。

    // 函数式组件(无状态组件)
    function Hello() {
      return <h1>Hello,jianan</h1>
    }
  • class组件(有状态组件)
    使用class定义、extends继承React.Component。有state进行数据的存储和管理,同时还可以拥有props,有生命周期函数。

    // class组件(有状态组件)
    class Hello extends React.Component {
      render() {
        return <h1>Hello jianan</h1>
      }
    }

    无状态组件和有状态组件的使用规则

  1. 因为数据的更改都是根据状态进行更改的,如果只是单纯的处理一些逻辑,而不需要改变数据的值就使用无状态组件。我们可以使用props进行组件间的通信和传值。
  2. 如果需要改变某些数据的话,或是想要存储一些数据并且想要对这些数据进行一些增删改查的话,那么就应该使用有状态组件。我们使用的是state,数据会发生变化就会触发生命周期这些函数。

无状态组件和有状态组件传值的取用

  • 无状态组件
    使用props传值时,使用props.属性名进行取用。
  • 有状态组件
    使用props传值时,使用this.props.属性名进行取用。使用state定义状态时,使用this.state.属性名进行取用。

==一般数据会通过父组件进行传递,这样就可以进行统一的数据管理,在父级进行一个集中的数据管理。以上是在没有使用redux的情况下,如果使用了redux的话,就会在redux中进行状态管理。==

有状态组件

本篇文章我们先来学习有状态组件:
有状态的组件需要使用render方法进行渲染,是生命周期里面非常基础和底层的方法,一定要用它来进行渲染

<script type="text/babel">
    class Hello extends React.Component {// 有状态的组件需要使用render方法进行渲染,是生命周期里面非常基础和底层的方法,一定要用它来进行渲染
        render() {
            return <h1>hello weiyu</h1>
        }
    }
    ReactDOM.render(
        <Hello/>,
        document.getElementById("root")
    )
</script>

有状态组件props传值

需要传什么值直接写在组件的上面,渲染的时候直接使用单花括号 { this.props.name }

<div id="root"></div>
<script type="text/babel">
    class Hello extends React.Component {
        render() {
            return <div>
                <h1>这是一个有状态组件</h1>
                <h1>姓名:{this.props.name}</h1>
                <h1>年龄:{this.props.age}</h1>
                <h1>性别:{this.props.sex}</h1>
            </div>
        }
    }
    ReactDOM.render(
        <Hello name="weiwei" age="18" sex="男"/>,
        document.getElementById("root")
    )
</script>

有状态组件state

有状态组件中state在实际开发中通常采用以下写法:

<div id="root"></div>
<script type="text/babel">
    class Hello extends React.Component {
        state = {
            age: '16',
            sex: '男'
        }
        render() {
            return <div>
                <h1>这是一个有状态组件</h1>
                <h1>姓名:{this.props.name}</h1>
                <h1>年龄:{this.state.age}</h1>
                <h1>性别:{this.state.sex}</h1>
            </div>
        }
    }
    ReactDOM.render(
        <Hello name="weiwei"/>,
        document.getElementById("root")
    )
    
</script>

==怎么选择使用有状态组件还是无状态组件?我们开发中更多的应该去使用哪种组件?==

答:更多时间尽可能的去选择使用无状态组件,因为如果是有状态组件,它就会触发生命周期所对应的一些函数。状态改变,就会触发虚拟dom重新渲染,它就会影响当前项目的运行,除非是需要对数据做一些存储、处理等,这个时候就选择有状态组件。

事件处理

事件处理函数的相关语法

React元素的事件处理和DOM元素很相似,但是语法上有些不同,React事件的命名采用小驼峰(camelCase),而不是纯小写。使用JSX语法时需要传入一个函数作为事件处理函数,而不是一个字符串。

<button onclick='fn()'>点击事件</button>
// React里
<button onClick={fn}>点击事件</button>

==另外在React中阻止默认事件不能通过返回false的形式,而是要使用preventDefault==

<a href="#" onclick="console.log('hello');return false">click</a>
handleClick(e) {
  e.preventDefault()
  console.log('hello')
}

<a href="#" onClick={handleClick}>click</a>

事件处理函数中的this

在JS中,class方法默认不会绑定this,如果我们忘记绑定this.handleClick并且把它传入了onClick,当我们调用这个函数的时候this的值为undefined。

class Hello extends React.Component {
  constructor() {
    super()
    // 如果不在constructor绑定this打印出来的值是undefined
    this.updateInfo = this.updateInfo.bind(this)
  }
  updateInfo() {
    console.log(this) 
  }
  updateState() {
    console.log(this)
  }
  updateAge() {
    console.log(this)
  }
  render() {
    return <div>
      <button onClick={this.updateInfo}>更新信息</button>
      {/* 像下面这样进行绑定也是可行的 */}
      <button onClick={this.updateState.bind(this)}>更新状态</button>
      <button onClick={() => this.updateAge()}>更新年龄</button>
    </div>
  }
}

==或者使用下面这种用箭头函数赋值的方式来定义函数,这是在工作中最为常用的方法:==

class Hello extends React.Component {
  updateInfo = () => {
    console.log(this)
  }
  render() {
    return <button onClick={this.updateInfo}>更新信息</button>
  }
}

下面给一个完整的例子,大家可以参考:
1.点击按钮可以进行年龄的更新 2.点击第二个按钮进行 true 和 false 的切换

<script type="text/babel">
    class Hello extends React.Component {
        state = {
            name: 'beiyu',
            age: 14,
            flag: true
        }
        updateInfo() {
            console.log(this)
            this.setState({
                age: 5
            })
        }
        updateState() {
            this.setState({
                flag: !this.state.flag
            })
        }
        render() {
            return <div>
                <h1>这是一个有状态组件</h1>
                <h1>姓名:{this.state.name}</h1>
                <h1>年龄:{this.state.age}</h1>
                <button onClick={this.updateInfo.bind(this)}>更新年龄</button>
                <button onClick={() => this.updateState()}>{this.state.flag ? 'TRUE' : 'FALSE' }</button>
            </div>
        }
    }
    ReactDOM.render(
        <Hello/>,
        document.getElementById("root")
    )
</script>

事件处理&条件处理

我们通过例子来学习:根据登录状态来展示不同的组件,true展示login组件,false展示logout组件

<script type="text/babel">
     function Login() {
         return <button>login</button>
     }
     function Logout() {
         return <button>logout</button>
     }
     class Hello extends React.Component {
         state = {
             isLogin: true
         }
         updateState = () => {
             this.setState({
                 isLogin: !this.state.isLogin
             })
         }
         
         render() {
             // const isLogin = this.state.isLogin
             const { isLogin } = this.state
             return <div>
                 <h1>这是一个有状态组件</h1>
                 { isLogin ? <Login/> : <Logout/> }
                 <button onClick={this.updateState}>更新状态</button>
             </div>
         }
     }
     ReactDOM.render(
         <Hello/>,
         document.getElementById("root")
     )
 </script>

==React中为什么要使用setState修改状态?==
答:React没有实现类似于Vue2的Object.defineProperty或者是Vue3的proxy方式来监听数据的变化,所以必须通过setState来告知react状态的改变,setState是继承自Component,当我们调用setState的时候会重新执行render方法

受限组件

Vue事项了响应式数据,但是React中不具备响应式特性,所以在应用中有很多东西需要我们手动完成

<script type="text/babel">
    class Hello extends React.Component {
        render() {
            return <input type="text" value="123" />
        }
    }
    ReactDOM.render(
        <Hello/>,
        document.getElementById("root")
    )
</script>

此时Hello作为一个受限组件渲染出来之后,我们去输入输入框任何值都无效,如果要响应用户输入的值,就必须使用onChange事件。
下面我们来进行改写,并且实现数据的双向绑定

<div id="root2"></div>
<script type="text/babel">
    class App extends React.Component {
        state = {
            value: 'hello'
        }
        change = (event) => {
            console.log(event);
            this.setState({
                value: event.target.value
            })
        }
        render() {
            return <div>
                <input type="text" value={this.state.value} onChange={this.change} />
                <h2>{this.state.value}</h2>
            </div>
        }
    }
    ReactDOM.render(
        <App/>,
        document.getElementById("root2")
    )
</script>

给input绑定onChange事件,然后在change函数中给value赋值event.target.value
==这里我们在函数中传入了event参数,打印出来就可以看见event.target.value就是我input中输入的值==

在这里插入图片描述

双向绑定效果:

在这里插入图片描述

最后

本期给大家介绍了有状态组件以及事件处理,关于本篇中的案例,大家可以自己动手操作实现以下,后面会继续给大家介绍使用react实现表单的一些操作~

欢迎关注,持续更新!!>>>>>

相关文章
|
11月前
|
缓存 前端开发 JavaScript
React Hooks深度解析与最佳实践:提升函数组件能力的终极指南
🌟蒋星熠Jaxonic,前端探索者。专注React Hooks深度实践,从原理到实战,分享状态管理、性能优化与自定义Hook精髓。助力开发者掌握函数组件的无限可能,共赴技术星辰大海!
React Hooks深度解析与最佳实践:提升函数组件能力的终极指南
|
缓存 前端开发 数据安全/隐私保护
如何使用组合组件和高阶组件实现复杂的 React 应用程序?
如何使用组合组件和高阶组件实现复杂的 React 应用程序?
493 68
|
缓存 前端开发 Java
在 React 中,组合组件和高阶组件在性能方面有何区别?
在 React 中,组合组件和高阶组件在性能方面有何区别?
448 67
|
前端开发 JavaScript 安全
除了高阶组件和render props,还有哪些在 React 中实现代码复用的方法?
除了高阶组件和render props,还有哪些在 React 中实现代码复用的方法?
554 62
|
前端开发
React 中高阶组件的原理是什么?
React 中高阶组件的原理是什么?
368 57
|
移动开发 前端开发 JavaScript
React音频播放列表组件:常见问题、易错点与解决方案
本文介绍了在React中实现音频播放列表时常见的挑战及解决方案。通过基础实现、常见问题分析和最佳实践,帮助开发者避免状态管理、生命周期控制和事件处理中的陷阱。关键点包括使用`useRef`操作音频元素、`useState`同步播放状态、全局状态管理防止多音频同时播放、以及通过`useEffect`清理资源。还提供了代码示例和跨浏览器兼容性处理方法,确保高效实现功能并减少调试时间。
527 30
|
移动开发 前端开发 UED
React 音频音量控制组件 Audio Volume Control
在现代Web应用中,音频播放功能不可或缺。React以其声明式编程和组件化开发模式,非常适合构建复杂的音频音量控制组件。本文介绍了如何使用HTML5 `&lt;audio&gt;`元素与React结合,实现直观的音量控制系统,并解决了常见问题如音量范围不合理、初始音量设置及性能优化等,帮助开发者打造优秀的音频播放器。
581 27
|
编解码 前端开发 开发者
React 图片组件样式自定义:常见问题与解决方案
在 React 开发中,图片组件的样式自定义常因细节问题导致布局错乱、性能损耗或交互异常。本文系统梳理常见问题及解决方案,涵盖基础样式应用、响应式设计、加载状态与性能优化等,结合代码案例帮助开发者高效实现图片组件的样式控制。重点解决图片尺寸不匹配、边框阴影不一致、移动端显示模糊、加载失败处理及懒加载等问题,并总结易错点和最佳实践,助力开发者提升开发效率和用户体验。
724 22
|
移动开发 前端开发 开发者
React 音频播放控制组件 Audio Controls
本文介绍了如何使用React构建音频播放控制组件,涵盖HTML5 `&lt;audio&gt;`标签和React组件化思想的基础知识。针对常见问题如播放状态管理、进度条更新不准确及跨浏览器兼容性,提供了详细的解决方案和代码示例。同时,还总结了易错点及避免方法,如确保音频加载完成再操作、处理音频错误等,帮助开发者实现稳定且功能强大的音频播放器。
616 11
|
移动开发 前端开发 UED
React 音频进度条组件 Audio Progress Bar
在现代Web开发中,音频播放功能不可或缺。使用React构建音频进度条组件,不仅能实现播放控制和拖动跳转,还能确保代码的可维护性和复用性。本文介绍了如何利用HTML5 `&lt;audio&gt;`标签的基础功能、解决获取音频时长和当前时间的问题、动态更新进度条样式,并避免常见错误如忘记移除事件监听器和忽略跨浏览器兼容性。通过这些方法,开发者可以打造高质量的音频播放器,提升用户体验。
733 6