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实现表单的一些操作~

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

猜你喜欢

转载自blog.csdn.net/weixin_45745641/article/details/123365106