React 从零开始
4.1 React 组件介绍
-
使用React就是在用组件 -
组件表示页面中的部分功能 -
组合多个组件实现完整的页面功能
可复用、独立、可组合
4.2 React 组件的两种创建方式
4.2.1 使用函数创建
函数组件:使用 JS 的函数(或箭头函数)创建的组件
-
函数名必须大写字母开头,为了区分组件和普通 React 元素 -
函数组件必须有返回值,表示该组件的结构 -
如果返回值为null,表示不渲染任何内容
用函数名作为组件标签名,组件标签可以是单标签也可以说双标签
function Hello() {
return <div>这是一个函数组件</div>;
}
ReactDOM.render(<Hello />, document.getElementById("root"));
4.2.2 使用类创建
类组件:使用 ES6 的 class 创建的组件
-
类名称必须大写字母开头 -
类组件继承 React.Component 父类,为了使用父类中提供的方法和属性 -
类组件必须提供 render() 方法 -
render() 方法必须有返回值,表示该组件结构 class Hello extends React.Component {
render() {
return <div>类组件</div>
}
}
ReactDOM.render(<Hello />, document.getElementById("root"))
4.2.3 抽离组件为独立 JS 文件
- 创建 Hello.js
- 在 Hello.js 中导入 React
- 创建组件(函数或类)
- 在 Hello.js 中导出该组件
- 在 index.js 中导入 Hello 组件
- 渲染组件
Hello.js
import React from 'react'
class Hello extends React.Component{
render() {
return (
<div>抽离的JS中的组件</div>
)
}
}
export default Hello
index.js
import React from "react"
import ReactDOM from "react-dom"
import "./index.css"
import Hello from "./Hello"
ReactDOM.render(<Hello />, document.getElementById("root"))
4.3 React 事件处理
4.3.1 事件绑定
on+事件名称={事件处理程序},事件采用驼峰命名法
例如 onClick={() => {}}
class Opp extends React.Component {
handleClick() {
console.log("单击事件")
}
render() {
return <button onClick={this.handleClick}>点点看</button>
}
}
ReactDOM.render(<Opp />, document.getElementById("root"))
function Opp() {
function handleClick() {
console.log("函数单击事件")
}
return <button onClick={handleClick}>点一点</button>
}
ReactDOM.render(<Opp />, document.getElementById("root"))
4.3.2 事件对象
可以通过事件处理程序的参数获取到事件对象
事件对象叫做合成事件,兼容所有浏览器
class Opp extends React.Component {
handleClick(e) {
e.preventDefault()
console.log("a标签的单击事件")
}
render() {
return (
<a href='http://baidu.com' onClick={this.handleClick}>
事件对象
</a>
)
}
}
4.4 有状态组件和无状态组件
- 函数组件叫无状态组件,类组件叫有状态组件
- 状态即数据
- 函数组件无状态,只负责数据展示 静态
- 类组件有状态,负责更新UI 动态
4.5 组件中的 state 和 setState
4.5.1 state 的基本使用
- 状态(state)即数据,是组件内部私有数据,只能在组件内部使用
- state 的值是对象,表示一个组件中可以有多个数据
- 通过 this.state 来获取状态
class Opp extends React.Component {
state = {
count: 0
}
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
</div>
)
}
}
4.5.2 setState() 修改状态
-
状态是可变的 -
this.setState({要修改的数据}) -
不要直接修改 state中的值 -
steState() 作用:1.修改 state 2.更新UI class Opp extends React.Component {
state = {
count: 0
}
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
<button
onClick={() => {
this.setState({
count: this.state.count + 1
})
}}
>
+1
</button>
</div>
)
}
}
4.5.3 从 JSX 中抽离事件处理程序(代码优化)
将逻辑抽离到单独的方法中,保证 JSX 结构清晰
class Opp extends React.Component {
state = {
count: 0,
}
onIncrement() {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
<button onClick={(this, this.onIncrement)}>+1</button>
</div>
)
}
}
报错:抽离出来的 this 是 undefined ,下一小节讲解决
4.6 事件绑定 this 指向
4.6.1 箭头函数
箭头函数自身不绑定 this, reander() 方法中的 this 为组件实例,可以获取到 setState()
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
<button onClick={() => this.onIncrement()}>+1</button>
</div>
)
}
4.6.2 Function.prototype.bind()
利用 ES5 中的 bind 方法,将事件处理程序中的 this 与组件实例绑定到一起
class Opp extends React.Component {
constructor() {
super()
state = {
count: 0,
}
this.onIncrement = this.onIncrement.bind(this)
}
onIncrement() {
this.setState({
count: this.state.count + 1,
})
}
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
<button onClick={this.onIncrement}>+1</button>
</div>
)
}
}
4.6.3 class 的实例方法(推荐)
利用箭头函数形式的 class 实例方法
class Opp extends React.Component {
state = {
count: 0
}
onIncrement = () => {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
<button onClick={this.onIncrement}>+1</button>
</div>
)
}
}
4.7 表单处理
4.7.1 受控组件
可变状态的值受到 React 控制的表单元素
React 将 state 与表单元素值 value 绑定到一起,由 state 的值来控制表单元素的值
- 在 state 中添加一个状态,作为表单元素的 value 值(控制表单元素值的来源)
- 给表单元素绑定 change 事件,将表单元素的值设置为 state 的值(控制表单元素值的变化)
class Opp extends React.Component {
state = {
txt: "",
}
handleChange = (e) => {
this.setState({
txt: e.target.value
})
}
render() {
return (
<div>
<input
type='text'
value={this.state.txt}
onChange={this.handleChange}
/>
</div>
)
}
}
4.7.2 多表单元素处理(代码优化)
-
给表单元素添加 name 属性,名称与 state 相同 -
根据表单元素类型获取对应值 -
在 change 事件处理程序中通过 [name] 来修改对应的 state import React from "react"
import ReactDOM from "react-dom"
class Opp extends React.Component {
state = {
txt: "",
content: "",
city: "bj",
isChecked: false,
}
handleForm = (e) => {
const target = e.target
const value = target.type === "checkbox" ? target.checked : target.value
const name = target.name
this.setState({
[name]: value,
})
}
render() {
return (
<div>
{}
<input
type='text'
name='txt'
value={this.state.txt}
onChange={this.handleForm}
/>
<br />
{}
<textarea
name='content'
value={this.state.content}
onChange={this.handleForm}
></textarea>
<br />
{}
<select
name='city'
value={this.state.city}
onChange={this.handleForm}
>
<option value='bj'>北京</option>
<option value='sh'>上海</option>
<option value='cs'>长沙</option>
</select>
<br />
{}
<input
name='isChecked'
type='checkbox'
checked={this.state.isChecked}
onChange={this.handleForm}
></input>
</div>
)
}
}
ReactDOM.render(<Opp />, document.getElementById("root"))
4.7.3 非受控组件(DOM方式)了解
借助于 ref ,使用原生 DOM 方式来获取表单元素值
ref作用:获取 DOM 或组件
- 调用 React.createRef() 方法创建一个 ref 对象
- 将创建好的 ref 对象添加到文本框中
- 通过 ref 对象获取到文本框的值
import React from "react"
import ReactDOM from "react-dom"
class Opp extends React.Component {
constructor() {
super()
this.txtRef = React.createRef()
}
getTxt = () => {
console.log("文本框的值为:", this.txtRef.current.value)
}
render() {
return (
<div>
<input type='text' ref={this.txtRef} />
<button onClick={this.getTxt}>文本框的值</button>
</div>
)
}
}
ReactDOM.render(<Opp />, document.getElementById("root"))
总结
今天学习了以下内容: React 组件基础 1.组件的两种创建方式:函数组件和类组件 2.无状态(函数)组件,负责静态结构展示 3.有状态(类)组件,负责更新 UI,让页面动起来 4.绑定事件注意this指向问题 5.推荐使用受控组件来处理表单
|