【React系列二】—React学习历程的分享

一、表单处理

受控组件

  • HTML 中的表单元素是可输入的,也就是有自己的可变状态

  • 而 React 中可变状态通常保存在state中,并且只能通过 setState() 方法来修改

  • React 将 state 与表单元素值 value 绑定在一起,有 state 的值来控制表单元素的值

  • 受控组件就是值受到react控制的表单元素

javascript 复制代码
// 受控组件
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()
    const { username, password } = this.state
    alert(`用户名是:${username}, 密码是:${password}`)
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        用户名:
        <input onChange={this.saveUsername} type="text" name="username" />
        密码:
        <input onChange={this.savePassword} type="password" name="password" />
        <button>登录</button>
      </form>
    )
  }
}

非受控组件

  • 说明:借助于 ref,使用原生 DOM 方式获取表单元素值

  • ref 的作用:获取 DOM 或者组件

javascript 复制代码
// 非受控组件
class Login extends React.Component {
  handleSubmit = (event) => {
    event.preventDefault()
    const { username, password } = this
    alert(`用户名是:${username.value}, 密码是:${password.value}`)
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        用户名:
        <input ref={(c) => (this.username = c)} type="text" name="username" />
        密码:
        <input ref={(c) => (this.password = c)} type="password" name="password" />
        <button>登录</button>
      </form>
    )
  }
}

总结

  • 组件的两种创建方式:函数组件和类组件

  • 无状态(函数)组件,负责静态结构展示

  • 有状态(类)组件,负责更新 UI,让页面动起来

  • 绑定事件注意 this 指向

  • 推荐使用受控组件来处理表单

  • 完全利用 JS 语言的能力创建组件,这是 React 的思想

二、组件实例核心---state

state 是组件实例对象最重要的属性,值为对象。又称为状态机,通过更新组件的 state 来更新对应的页面显示。

知识要点:

  • 初始化 state
  • React 中事件绑定
  • this 指向问题
  • setState 修改 state 状态
  • constructor 、render 、自定义方法的调用次数
javascript 复制代码
<script type="text/babel">
  class Weather extends React.Component {
    // 调用一次
    constructor(props) {
      super(props)
      // 初始化 state
      this.state = { isHot: true, wind: '微风' }
      // 解决 this 指向问题
      this.changeWeather = this.changeWeather.bind(this)
    }
    // 调用 1+N 次
    render() {
      // 读取状态
      const { isHot } = this.state
      return <h1 onClick={this.changeWeather}>今天天气 {isHot ? '炎热' : '凉爽'}</h1>
    }
    // 点一次调一次
    changeWeather() {
      const isHot = this.state.isHot
      // 对 state 的修改是一种合并而非替换,即 wind 依然存在
      this.setState({ isHot: !isHot })
    }
  }

  ReactDOM.render(<Weather />, document.getElementById('test'))
</script>

三、组件实例核心---props

每个组件对象都有 props 属性,组件标签的属性都保存在 props 中。

props 是只读的,不能修改。

可以给组件传递任意类型的props数据

基本使用

javascript 复制代码
<script type="text/babel">
  class Person extends React.Component {
    render() {
      const { name, age, sex } = this.props
      return (
        <ul>
          <li>姓名:{name}</li>
          <li>性别:{sex}</li>
          <li>年龄:{age}</li>
        </ul>
      )
    }
  }

  // 类似于标签属性传值
  ReactDOM.render(<Person name="Lily" age={19} sex="男" />, document.getElementById('test'))
</script>

批量传递

javascript 复制代码
<script type="text/babel">
  class Person extends React.Component {
    render() {
      const { name, age, sex } = this.props
      return (
        <ul>
          <li>姓名:{name}</li>
          <li>性别:{sex}</li>
          <li>年龄:{age}</li>
        </ul>
      )
    }
  }

  const obj = { name: 'Ben', age: 21, sex: '女' }
  ReactDOM.render(<Person {...obj} />, document.getElementById('test'))
</script>

限制props传递类型

在React15.5版本之前,React身上有一个propTypes属性可以直接使用,在15.5版本之后,把propTypes单独封装成一个模块,需要额外导入使用

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

<script type="text/babel">
  class Person extends React.Component {
    render() {
      const { name, age, sex } = this.props
      return (
        <ul>
          <li>姓名:{name}</li>
          <li>性别:{sex}</li>
          <li>年龄:{age}</li>
        </ul>
      )
    }
  }

  // 类型和必要性限制
  Person.propTypes = {
    name: PropTypes.string.isRequired,
    sex: PropTypes.string,
    age: PropTypes.number,
    // 限制 speak 为函数
    speak: PropTypes.func,
  }

  // 指定默认值
  Person.defaultProps = {
    sex: 'male',
    age: 19,
  }

  ReactDOM.render(<Person name="Vue" sex="male" age={11} speak={speak} />, document.getElementById('test'))

  function speak() {
    console.log('speaking...')
  }
</script>

类组件的构造器使用props

构造函数一般用在两种情况:

  • 通过给 this.state 赋值对象来初始化内部 state
  • 为事件处理函数绑定实例
javascript 复制代码
constructor(props) {
  super(props)
  // 初始化 state
  this.state = { isHot: true, wind: '微风' }
  // 解决 this 指向问题
  this.changeWeather = this.changeWeather.bind(this)
}

函数组件使用props

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

<script type="text/babel">
  function Person(props) {
    const { name, age, sex } = props
    return (
      <ul>
        <li>姓名:{name}</li>
        <li>性别:{sex}</li>
        <li>年龄:{age}</li>
      </ul>
    )
  }
  Person.propTypes = {
    name: PropTypes.string.isRequired,
    sex: PropTypes.string,
    age: PropTypes.number,
  }

  Person.defaultProps = {
    sex: '男',
    age: 18,
  }

  ReactDOM.render(<Person name="jerry" />, document.getElementById('test'))
</script>

有不明白的或者有其他问题的可以评论区留言噢

今天的知识分享就到这里啦~希望大家在这能学到知识一起分享一起进步,成为更好的自己!

相关推荐
kyriewen12 小时前
折腾了半年 AI 编程工作流,最后发现效率瓶颈是桌上那块屏幕
前端·javascript·ai编程
蜗牛前端12 小时前
codex 全流程开发上线的高颜值礼簿小程序
前端·微信小程序
大龄秃头程序员13 小时前
我在图文流 App 里落地双层缓存、弱网降级与 OOM 治理
前端
老王以为13 小时前
React Renderer 分离的多平台架构
前端·react native·react.js
hunterandroid13 小时前
Kotlin Coroutines 与 Flow:让异步任务更清晰
前端
Bigger13 小时前
从零搭建 AI 代码审查服务:一份前端也能看懂的 Python 学习笔记
前端·ci/cd·ai编程
lichenyang45314 小时前
JSAPI、NAPI、Biz、Imp:ASCF Demo 如何真正调用系统能力和 C++ 能力
前端
lichenyang45314 小时前
IPC、JSVM、UIThread、libuv:ASCF 架构图里最容易混的几个词
前端
用户0595401744614 小时前
Redis记忆存储故障恢复测试踩坑实录:手动测试让我漏掉了2个一致性Bug
前端·css
用户21366100357214 小时前
Vue2脚手架工程化与Axios集成
前端·vue.js