函数组件
null
// 使用普通函数创建组件:
function Hello() {
return <div>这是我的第一个函数组件!</div>
}
function Button() {
return <button>按钮</button>
}
// 使用箭头函数创建组件:
const Hello = () => <div>这是我的第一个函数组件!</div>
// 使用 双标签 渲染组件:
<Hello></Hello>
ReactDOM.render(<Hello></Hello>, root)
// 使用 单标签 渲染组件:
<Hello />
ReactDOM.createRoot(document.querySelector('#root')).render(<Hello></Hello>)
小结:
内容
定义组件
// 导入 React
import React from 'react'
class Hello extends React.Component {
render() {
return <div>Hello Class Component!</div>
}
}
ReactDOM.render(<Hello />, root)
// 只导入 Component
import { Component } from 'react'
class Hello extends Component {
render() {
return <div>Hello Class Component!</div>
}
}
使用组件
ReactDOM.createRoot(document.querySelector('#root')).render(<Hello></Hello>)
总结
实现方式
核心代码
// index.js
//直接导入
import Hello from './Hello'
//按需导入
// import {Hello} from './Hello'
// 渲染导入的Hello组件
ReactDOM.createRoot(document.querySelector('#root')).render(<Hello></Hello>)
// Hello.js
import { Component } from 'react'
class Hello extends Component {
render() {
return <div>Hello Class Component!</div>
}
}
// 导出Hello组件(默认导出)
export default Hello
//按需导出
// export {
// Hello
// }
内容:
静
态,不会发生变化),性能比较高动
态)比如计数器案例,点击按钮让数值+1, 0和1就是不同时刻的状态,当状态从0变成1之后,UI也要跟着发生变化。React想要实现这种功能,就需要使用有状态组件来完成。
内容:
state
,即数据,是组件内部的私有数据,只能在组件内部使用this.state.xxx
来获取状态核心代码
class Hello extends Component {
// 为组件提供状态
state = {
count: 0,
list: [],
isLoading: true
}
render() {
return (
<div>计数器</div>
)
}
}
this.state
来获取状态class Hello extends Component {
// ...
render() {
// 通过 this.state 来访问类组件的状态
return (
<div>计数器:{this.state.count}</div>
)
}
}
内容:
React注册事件与DOM的事件语法非常像
语法on+事件名 ={事件处理程序}
比如onClick={this.handleClick}
注意:React事件采用驼峰命名法,比如onMouseEnter
, onClick
核心代码
class App extends React.Component {
handleClick() {
console.log('点击事件触发')
}
render() {
return (
<div>
<button onClick={this.handleClick}>点我</button>
</div>
)
}
}
核心代码
function handleClick(e) {
e.preventDefault()
console.log('事件对象', e)
}
<a onClick={this.handleClick}>点我,不会跳转页面</a>
内容:
事件处理程序中的this指向的是undefined
render方法中的this指向的是当前react组件。只有事件处理程序中的this有问题
原因
undefined
class App extends React.Component {
state = {
msg: 'hello react'
}
handleClick() {
console.log(this.state.msg)
}
render() {
return (
<div>
<button onClick={this.handleClick}>点我</button>
</div>
)
}
}
总结:
undefined
内容:
解决事件处理程序中this指向问题主要有三种方式
方式1:箭头函数
class App extends React.Component {
state = {
msg: 'hello react'
}
handleClick() {
console.log(this.state.msg)
}
render() {
return (
<div>
<button onClick={() => this.handleClick()}>点我</button>
</div>
)
}
}
bind
class App extends React.Component {
state = {
msg: 'hello react'
}
handleClick() {
console.log(this.state.msg)
}
render() {
return (
<div>
<button onClick={this.handleClick.bind(this)}>点我</button>
</div>
)
}
}
class App extends React.Component {
state = {
msg: 'hello react'
}
handleClick = () => {
console.log(this.state.msg)
}
render() {
return (
<div>
<button onClick={this.handleClick}>点我</button>
</div>
)
}
}
总结
// ES6
class Person1 {
// 类的 构造函数
constructor() {
// 构造函数中的 this 就是实例对象
console.log(this)
this.name = 'jack'
this.fn = () => {
console.log(this)
}
}
// 上述写法简化语法:
// name = 'jack'
// fn = () => {}
// 这个形式的方法会被添加到原型中
sayHi() {}
}
说明:
fn = () => {} 这种形式的语法是简化语法(语法糖),书写会更简单。实际上,完整的写法是:
constructor() {
this.fn = () => {}
}
即:在构造函数中,给 this 添加了一个方法 fn
为什么可以解决 this 指向问题呢?
因为 constructor 中创建的箭头函数,内部的 this 会指向 constructor 中的 this
而 constructor 中的 this 就是实例对象(也就是我们需要的 this)
内容:
this.setState({ 要修改的部分数据 })
核心代码
class Hello extends Component {
state = {
count: 0
}
handleClick = () => {
this.setState({
count: 10
})
}
render() {
return (
<div>
<h1>计数器:{this.state.count}</h1>
<button onClick={this.handleClick}>+1</button>
</div>
)
}
}
// 在 count 当前值的基础上加 1
this.setState({
count: this.state.count + 10
})
总结:
setState()
内容:
核心代码:
state = {
count: 0,
list: [1, 2, 3],
person: {
name: 'jack',
age: 18
}
}
// 【不推荐】直接修改当前值的操作:
this.state.count++
++this.state.count
this.state.count += 1
this.state.count = 1
// 只要是数组中直接修改当前数组的方法都不能用!
this.state.list.push(123)
this.state.person.name = 'rose'
// 【推荐】不是直接修改当前值,而是创建新值的操作:
this.setState({
count: this.state.count + 1,
list: [...this.state.list, 123],
person: {
...this.state.person,
// 要修改的属性,会覆盖原来的属性,这样,就可以达到修改对象中属性的目的了
name: 'rose'
}
})
内容:
state
中的,并且要求状态只能通过setState
进行修改核心代码:
class App extends React.Component {
state = {
msg: 'hello react'
}
handleChange = (e) => {
this.setState({
msg: e.target.value
})
}
render() {
return (
<div>
<input type="text" value={this.state.msg} onChange={this.handleChange}/>
</div>
)
}
}
总结:
非受控组件借助于ref,使用原生DOM的方式来获取表单元素的值
内容
ref
核心代码
// 1 导入 createRef 函数( 用来创建 ref 对象 )
import { createRef } from 'react'
class Hello extends Component {
// 2 调用 createRef 函数来创建一个 ref 对象
// ref 对象的名称(txtRef)可以是任意值
// 命名要规范: txt(DOM 元素的自己标识) + Ref
txtRef = createRef()
handleClick = () => {
// 文本框对应的 DOM 元素
// console.log(this.txtRef.current)
// 4 获取文本框的值:
console.log(this.txtRef.current.value)
}
render() {
return (
<div>
{/*
3 将创建好的 ref 对象,设置为 input 标签的 ref 属性值
作用:将 ref 和 input DOM 绑定到一起,将来在通过 this.txtRef 拿到的就是当前 DOM 对象
*/}
<input ref={this.txtRef} />
<button onClick={this.handleClick}>获取文本框的值</button>
</div>
)
}
}