热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

React快速上手04基础特性JSX、Props、State、Lifecycle、Event、Style

目录01前言02开发环境搭建03脚手架创建项目一切都是组件04基础特性JSX、Props、State、Lifecycle、Event、Style05组件渲染控制06容器组件、展示组

《React 快速上手 - 04 基础特性 JSX、Props、State、Lifecycle、Event、Style》

目录
  • 01 前言
  • 02 开发环境搭建
  • 03 脚手架创建项目 一切都是组件
  • 04 基础特性 JSX、Props、State、Lifecycle、Event、Style
  • 05 组件渲染控制
  • 06 容器组件、展示组件
  • 07 前端路由 react-router
  • 08 状态管理 react-redux
  • 09 数据请求 fetch
  • 10 属性类型检查 prop-types
React 快速上手 – 04 基础特性 JSX、Props、State、Lifecycle、Event、Style

目标

掌握 react 的基础特性

  • 语法 JSX
  • 属性 Props
  • 状态 State
  • 生命周期 Lifecycle
  • 事件 Event
  • 样式 Style

基础特性

react.js 本身只是一个精简的类库,提供了几个特性或者说是工具,每个话题深入都可以长篇大论。

我这里只关注使用,毕竟轮子造出来还是用的,而不是观赏。

1. JSX 语法

我的理解 jsx 就是 html + 表达式 的混合体

1.1 请用 ( ... ) 把 jsx 代码包含起来

const Element1 = () => (

组件1 - 常量

)

这样写的理由

  • 低版本的兼容性
  • 多行书写不会报错

当然新版里如果你单行可以省略

1.2 必须有个顶级标签

错误
let Element4 = () => {
return (

组件4 - es6 箭头函数


组件4 - es6 箭头函数


)
}
正确
let Element4 = () => {
return (

组件4 - es6 箭头函数


组件4 - es6 箭头函数



)
}

如果你只有一个标签,自己本身就是顶级标签,无需加

1.3 { ... } 开始你的js表达式

function ElementShow(props) {
return (


字符串: {props.name}


日期变量: {props.date.toLocaleTimeString()}



)
}

分别打印 属性值、时间函数

1.4 对于没有子元素的标签来说,请关闭标签



结束符 /

codepen

https://codepen.io/ducafecat/…

2. 属性 Props

2.1 属性值 都是只读的

function ElementShow(props) {
props.isShow = true // 只读不能修改
...

打印截图

《React 快速上手 - 04 基础特性 JSX、Props、State、Lifecycle、Event、Style》

2.2 特殊的几个 属性值

记忆就行,和我们之前写 html 有些差异

我看着都是因为 js 中保留字关系

jsxhtml
tabIndexindex
classNameclass
htmlForfor

示例

const ElementProps = () => (


JSX 属性 tabIndex、className

)

2.3 默认使用驼峰格式 camelCase

错误
UserName="hello"
phone_number={12345678}
/>
正确
userName="hello"
phOneNumber={12345678}
/>

2.4 如果属性值为 true, 可以直接省略

错误
hidden={true}
/>
正确
hidden
/>

2.5 key 属性是怎么回事

示例


    {NavRoutes.map((route, index) => (

  • {route.title}

  • ))}

如果不写呢

《React 快速上手 - 04 基础特性 JSX、Props、State、Lifecycle、Event、Style》

看来是绕不过的

总结

react利用key来识别组件,它是一种身份标识标识

同层的唯一就行,不用全局唯一

避免使用数组的index作为
key

2.6 防注入攻击

代码

const jsCOntent= `
`
const ElementInject = () =>

{jsContent}

打印

《React 快速上手 - 04 基础特性 JSX、Props、State、Lifecycle、Event、Style》

内容在渲染之前都被转换成了字符串,这样可以有效地防止 XSS(跨站脚本) 攻击

2.7 childen 表示子节点对象

这个属性表示,当前组件嵌套的对象集合

render() {
return(

First
Second
Third

)
}

RadioGroup
props.childen 就是这三个
RadioButton

你可能会问这有什么用,我们可以用来加工呀,各种循环、克隆、修改,当然我是不太推荐这样去修改 dom 对象

codepen

https://codepen.io/ducafecat/…

3. 状态 State

组件内部的数据管理对象,自动状态控制

有的同学可能对 MVVM 比较了解,一定会说 React 怎么没有双向绑定

这可能就是设计思想问题了,不想给工具赋予过多负重,轻巧才灵活,下一章,我会通过一个函数解决双向绑定来处理表单操作,就几行代码

这里我们还是谈谈基础操作,懂得同学可以 PASS

3.1 初始化

class ElementStateStatic extends Component {
constructor(props) {
super(props)
this.state = {date: new Date()}
}
render() {
return

初始时间 => {this.state.date.toLocaleString()}


}
}

constructor 是组件构造函数,给
this.state 初始值时 要用
key/val 形式的对象

jsx 中使用时直接
this.state.data 对象调用即可

3.2 更新

class ElementStateUpdate extends Component {
constructor(props) {
super(props)
this.date = props.date
this.state = {date: new Date()}
}
componentDidMount() {
if (this.date !== undefined) {
// 传值方式
this.setState({date: this.date})
// 函数方式
// this.setState((state, props) => {
// return {date: this.date}
// })
}
}
render() {
return

更新时间 => {this.state.date.toLocaleString()}


}
}

需要使用
this.setState 函数设置

简单操作,直接 传入 key / value 的对象

  • 如果需要之前的 state 或者组件属性 props ,需要写成

this.setState((state, props) => {
let date = state.data
date = date.addDay(10)
return {date}
})

codepen

https://codepen.io/ducafecat/…

4. 生命周期 Lifecycle

4.1 组件有三种状态

状态说明
Mount已插入真实 DOM
Update正在被重新渲染
Unmount已移出真实 DOM

4.2 组件周期函数

《React 快速上手 - 04 基础特性 JSX、Props、State、Lifecycle、Event、Style》

状态说明
componentDidMount在第一次渲染后调用,只在客户端。
shouldComponentUpdate返回一个布尔值。在组件接收到新的props或者state时被调用。
componentDidUpdate在组件完成更新后立即调用。在初始化时不会被调用。
componentWillUnmount在组件从 DOM 中移除的时候立刻被调用。
getDerivedStateFromProps组件实例化后和接受新属性时将会调用 新增
getSnapshotBeforeUpdate在最新的渲染输出提交给DOM前将会立即调用 新增

4.3 示例打印周期过程

代码

class ElementLifecycle extends Component {
constructor(props) {
super(props)
this.date = props.date
this.state = {date: this.date}
}
componentDidMount() {
console.log('componentDidMount 在第一次渲染后调用')
if (this.date !== undefined) {
this.setState({date: this.date})
}
}
shouldComponentUpdate(nextProps, nextState) {
console.log(
'shouldComponentUpdate 在组件接收到新的props或者state时被调用',
nextProps,
nextState
)
return true // 返回一个布尔值,大家可以试着在这里返回 false
}
componentDidUpdate(prevProps, prevState) {
console.log(
'componentDidUpdate 在组件完成更新后立即调用',
prevProps,
prevState
)
}
componentWillUnmount() {
console.log('componentWillUnmount 在组件从 DOM 中移除的时候立刻被调用')
}
render() {
return

时间 => {this.state.date.toLocaleString()}


}
}

打印截图

《React 快速上手 - 04 基础特性 JSX、Props、State、Lifecycle、Event、Style》

codepen

https://codepen.io/ducafecat/…

4.4 react 16.x 新版本变动

4.4.1 计划取消 3 个生命周期函数

分别是 componentWillMount, componentWillReceiveProps, componentWillUpdate

理由是在新的升级中,存在漏洞(在Facebook上,他们维护了超过50,000个React组件。 )

注意:

弃用警告将在未来的16.x版本中启用,但旧版生命周期将继续运行至17.x版。

即使在17.x版中,仍然可以使用它们,但它们会以『UNSAFE_』为前缀被重命名,以表明它们可能会引起问题。我们还准备了一个自动化的脚本来在现有代码中对它们重新命名。

UNSAFE_componentWillMount()
UNSAFE_componentWillReceiveProps()
UNSAFE_componentWillUpdate()

4.4.2 新增 getDerivedStateFromProps

组件实例化后和接受新属性时将会调用

代码

// 组件
class ElementLifecycleNew extends Component {
constructor(props) {
super(props)
this.state = {}
}
static getDerivedStateFromProps(nextProps, prevState) {
console.log(
'getDerivedStateFromProps 组件实例化后和接受新属性时将会调用',
nextProps,
prevState
)
// return null // 无需改变 返回 null
return {
date: new Date('2011-11-11 11:11:11')
}
}
render() {
return

{this.state.date.toLocaleString()}


}
}
// 调用

如果你不想改变状态 state , 返回 null

4.4.3 新增 getSnapshotBeforeUpdate + componentDidUpdate

getSnapshotBeforeUpdate() 在最新的渲染输出提交给DOM前将会立即调用。它让你的组件能在当前的值可能要改变前获得它们。这一生命周期返回的任何值将会 作为参数被传递给
componentDidUpdate()

// 代码
class ElementLifecycleNew2 extends Component {
listRef = React.createRef()
constructor(props) {
super(props)
this.state = {
date: props.date
}
}
componentDidMount() {
console.log('componentDidMount')
this.setState({date: new Date('2011-11-22 22:22:22')})
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log('getSnapshotBeforeUpdate', prevProps, prevState, this.state)
return {
offset: 80
}
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log('componentDidUpdate', snapshot)
this.listRef.current.style.top = `${snapshot.offset}px`
}
render() {
return (
blue',
position: 'relative',
color: '#fff'
}}
>

{this.state.date.toLocaleString()}


ref={this.listRef}
red',
top: 0,
position: 'absolute'
}}
/>

)
}
}
// 调用

这个例子的流程是:

1. `componentDidMount` 中修改了 state 触发 `getSnapshotBeforeUpdate`
2. `getSnapshotBeforeUpdate` 获取修改前的 属性、状态,已修改的 状态,然后一个修改值 `offset`
3. `componentDidUpdate` 中的 `snapshot` 获取修改值 ,直接 `ref` `dom` 修改 `style`

简单说就是不修改 state 更新机制,来维护
dom,比如改改 宽 高 位置

5. 事件 Event

在 react 里使用事件,写法很多,这里采用官方推荐的方式

5.1 无参数传递

handleChange(e) {
...
}

class InputView extends Component {
constructor(props) {
...
this.handleChange = this.handleChange.bind(this)
}

使用
bind(this) 方式

...
OnChange={this.handleChange}
/>

5.2 有参数传递

handleChangeVal(val, e) {
console.log(val)
this.setState({value: e.target.value})
}

...
OnChange={this.handleChangeVal.bind(this, '123')}
/>

5.3 例子

class InputView extends Component {
constructor(props) {
super(props)
this.state = {value: ''}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(e) {
this.setState({value: e.target.value})
}
handleChangeVal(val, e) {
console.log(val)
this.setState({value: e.target.value})
}
handleSubmit(e) {
e.preventDefault() // 阻止事件
console.log('handleSubmit')
}
render() {
return (

type="text"
value={this.state.value}
OnChange={this.handleChange}
/>
type="text"
value={this.state.value}
OnChange={this.handleChangeVal.bind(this, '123')}
/>

{this.state.value}



)
}
}

codepen

https://codepen.io/ducafecat/…

6. 样式 Style

有两种方式维护样式

6.1 import 样式文件

.bg {
background-color: rgb(101, 40, 241);
color: white;
font-weight: 500;
}

import './base.css'

6.2 直接编写 style

const styles = {}
styles.fill = {
position: 'relative',
height: '200px',
width: '500px'
}
...

...
  • 混合使用

style={{
...styles.fill,
...styles.hsl,
background: `hsl(${params.h}, ${params.s}%, ${params.l}%)`
}}
>

可以发现这样的写法,对编程控制样式还是很有用的

本文代码

  • reactjs-example / 2-feature.js

参考

  • Index as a key is an anti-pattern
  • Introducing JSX
  • Rendering Elements
  • Components and Props
  • State and Lifecycle
  • Handling Events
  • lists-and-keys.html
  • React.Component

© 会煮咖啡的猫咪
微信 ducafecat
镜像 Git


推荐阅读
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
author-avatar
一个不需要幸福的男人丶
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有