JSX 语法
React中 使用 JSX 语法描述用户界面,他是一种 JavaScript 语法扩展
在 React 代码执行之前,Babel 会将 JSX 语法转换为标准的 JavaScript API
JSX 语法就是一种语法糖,让开发使用更舒适的代码构建用户界面
属性
如果属性值为字符串类型,需要加引号,属性名称推荐采用驼峰式命名法
const ele = <div gretting="hello"></div>
如果属性值为 JavaScript 表达式,属性值外面加大括号
const ele = <img src={user.avatarUrl}></img>
// 注意大括号外面不能加引号,JSX 会将引号中的内容识别为字符串,而不是表达式
JSX 单标记必须闭合
如果是JSX 单标记,必须闭合,否则报错
<img src={user.avatarUrl} />
className
为 JSX 添加类名,需要使用 className,而不是 class
<button className="rounded" />
JSX 自动展开数组
const arr = [<p>哈哈</p>, <p>哈哈</p>, <p>哈哈</p>]
const ele = <div>{arr}</div>
// 解析后
/*
<div>
<p>哈哈</p>
<p>哈哈</p>
<p>哈哈</p>
</div>
*/
三元运算符
循环
const list = [{
id: 1,
name: 'Jack',
age: 15
},{
id: 1,
name: 'Jack',
age: 15
},
{
id: 1,
name: 'Jack',
age: 15
}]
<ul>
list.map(item => <li key={item.id}>{item.name}</li>)
</ul>
事件
{/* 第一个参数为事件对象,不需传递 */}
<button onClick={this.eventHandler}>按钮</button>
{/* 需要传递事件对象 */}
<button onClick={(e) => this.eventHandler('arg', e)}>按钮</button>
{/* 最后一个参数即是事件对象,不许传递 */}
<button onClick={this.eventHandler.bind(null, 'arg')}>按钮</button>
class App extends Component {
constructor() {
super()
this.eventHandler.bind(this) // bind 返回一个全新的函数 第一个参数是this指向 第二个参数返回函数传递的参数
}
eventHandler(){}
}
样式
行内样式
class App extends Component {
render() {
const style = {width: 200, backgroundColor: 'red'}
return <div style={style}></div>
}
}
外链样式
import styles from './Button.module.css'
class Button extends Component {
render() {
return <div style={styles.rounded}></div>
}
}
全局样式
import './styles.css'
ref 属性
createRef
class Input extends Component {
constructor () {
super()
this.inputRef = React.createRef()
}
render(){
return (
<div>
<input ref={this.inputRef} />
<button onClick={() => conosle.log(this.inputRef.current)}>按钮</button>
</div>
)
}
}
函数参数
class Input extends Component {
render(){
return (
<div>
<input ref={(input) => this.input = input} />
<button onClick={() => conosle.log(this.input)}>按钮</button>
</div>
)
}
}
字符串参数
class Input extends Component {
render(){
return (
<div>
<input ref="username" />
<button onClick={() => conosle.log(this.refs.username)}>按钮</button>
</div>
)
}
}
获取组件实例
组件回顾
React 是基于组件的方式进行用户界面开发的. 组件可以理解为对页面中某一块区域的封装。
创建类组件
class App extends Component {
render(){
return (
<div></div>
)
}
}
创建函数组件
const Input = (props) => {
return (
<div>
<input />
</div>
)
}
注意
- 组件名称首字母必须大写,用以区分组件和普通标签
- jsx 语法外层必须要有一个根元素
组件 props
props 传递数据
在调用组件可以向组件内部传递数据,在组件中可以通过 props 对象获取外部传递进来的数据
<Person name="Kara" age="19" />
const Person = (props) => {
return (
<div>{props.name}{props.age}</div>
)
}
Person.defaultProps = {
age: "Jack",
age: 26
}
设置props 默认值
组件children
<Person>
<div>childrenDom</div>
</Person>
const Person = (props) => {
return (
<div>{props.children}</div>
)
}
单项数据流
- 在 React 中,关于数据流有一条原则,就是单项数据流动,自顶向下,从父组件到子组件
- 单项数据流特性要求我们共享数据要放置在上层组建中
- 子组件通过调用伏组件传递过来的方法更改数据
- 当数据发生更改时,React 会重新渲染组件树
- 单项数据流使组件的数据流动变得可预测,是定位程序错误变得简单
类组件状态 state
类组件除了能够从外部(props)接收状态数据以外还可以拥有自己的状态(state),此状态在组件内部可以被更新,状态更新 DOM 更新
组件内部的状态数据存储在组件类的 state 属性中,state属性值为对象类型,属性名称固定不可更改
class App extends Component {
contructor(){
super()
this.satate = {
person: {name: 'Kara', age: 19}
}
this.changePerson.bind(this)
}
changePerson() {
this.setState({
person: {
name: 'Jack',
age: 36
}
})
}
render () {
return (
<div>{this.state.person.name}</div>
<button onClick={this.changePerson}></button>
)
}
}
双向数据绑定
双向数据绑定是指,组件类中更新了状态,DOM 状态同步更新,DOM 更改了状态,组件类中同步更新。组件 <=> 视图。
要实现双向数据绑定需要用到表单元素和 state 状态对象。
类组件生命周期
在组件完成更新之前需要做某种逻辑或者计算,就需要用到快照
componentDidUpdate(prevProps, prevState, snapshot) {}
getSnapshotBeforeUpdate 方法会在组件完成更新之前执行,用于执行某种逻辑或计算,返回值可以在 componentDidUpdate 方法中的第三个参数中获取,就是说在组件更新之后可以拿到这个值再去做其他事情。
getSnapshotBeforeUpdate(prevProps, prevState) {
return 'snapshot'
}
context
通过 context 跨层级传递数据
// userContext.js
import React from "react"
const userContext = React.createContext("default value")
const UserProvider = userContext.Provider
const UserConsumer = userContext.Consumer
export { UserProvider, UserConsumer }
// App.js
import { UserProvider } from "./userContext"
class App extends Component {
render() {
return (
<UserProvider value="Hello React Context">
<A />
</UserProvider>
)
}
}
// C.js
import { UserConsumer } from "./userContext"
export class C extends Component {
render() {
return (
<div>
<UserConsumer>
{username => {
return <div>{username}</div>
}}
</UserConsumer>
</div>
)
}
}
表单回顾
受控表单
表单控件中的值由组件的 state 对象来管理,state对象中存储的值和表单控件中的值时同步状态的
非受控表单
表单元素的值由 DOM 元素本身管理。
class App extends Component {
constructor () {
this.onSubmit = this.onSubmit.bind(this)
}
onSubmit(e) {
console.log(this.username.value)
e.preventDefault();
}
render(
<form onSubmit={this.onSubmit}>
<input type="text" ref={username => this.username = username}/>
</form>
)
}
路由回顾
url地址与组件之间的对应关系,访问不同的url地址显示不同的组件。