------------------------------------------------基础-----------------------------------------------
一、 react 使用
-
npm i react react-dom
-
引入 react 和 react-dom 的 js
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
- 创建 React 元素
const title = React.createElement("h1", null, "Hello React");
- 渲染 React 元素到页面元素中
ReactDOM.render(title, document.getElementById("root"));
二、项目
1.初始化
npx create-react-app my-app
npm init react-app my-app
2.使用
import React from "react";
import ReactDOM from "react-dom";
const title = React.createElement("h1", null, "Hello React");
ReactDOM.render(title, document.getElementById("root"));
三、JSX
-
createEelement 不够直观,所以用 jsx
-
在 js 中写 html 格式的代码
-
jsx 是 ECMAScript 的语法扩展,需要用 babel 编译,脚手架中有该配置,@babel/preset-react
-
class 属性名使用驼峰命名法,小括号包裹 JSX
-
特殊属性名: class-> className \ for -> htmlFor \tabindex -> tabIndex
- 表达式
const name = 'jack'
const title = (
<h1>
hello,jsx,{name}
</h1>
)
ReactDOM.render(title, document.getElementById("root"));
- 条件渲染
const isLoading = true
const loadData = () => {
if(isLoading) {
return <div>loading</div>
}
return <div>数据加载完成,此处显示加载后的数据</div>
}
const title = (
<h1>
hello,jsx,{loadData}
</h1>
)
ReactDOM.render(title, document.getElementById("root"));
- 列表渲染
- map()
const songs = [
{id: 1,name: 'hahaha'},
{id: 2,name: 'xixixi'},
{id: 3,name: 'houhouhou'}
]
const list = (
<ul>
{songs.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
)
- 样式处理
- 行内样式 2) className
<h1 className="title" style={{color:'red'}}>
hahahah
</h1>
三、组件
- 组件是react核心:可复用、独立、可组合
- 创建
- 函数组件: 大写字符开头、必须有返回值、可用箭头函数
function Hello() {
return (
<div>组件组件</div>
)
}
ReactDom.render(<Hello/>,document.getElementById("root"))
- 类创建组件: 大写字母开头、必须继承React.Component父类、必须有render()、必须有返回值
class Hello extends React.Component {
render() {
return <div>hello</div>
}
}
ReactDom.render(<Hello/>,root)
- 抽离
- 每个组件放到单独的js文件中
- 创建hello.js
- 在hello.js导入React
- 创建组件(函数或类)
- 导出
- 导入
6) 渲染
//hello.js
import React from 'react'
class Hello extends React.Component {
render() {
return <div>hello</div>
}
}
export default Hello
//index
import Hello from './Hello'
ReactDom.render(<Hello/>,root)
- 事件绑定
// on+ 事件名称={事件处理程序} 驼峰命名法
class Hello extends React.Component {
handleClick() {
console.log('点击啦')
}
render() {
return <button onClick={this.handleClick}>hello</button>
}
}
//事件对象 -> 合成事件
class Hello extends React.Component {
handleClick(e) {
e.preventDefault()
console.log(e)
}
render() {
return <button onClick={this.handleClick}>hello</button>
}
}
- 有状态组件和无状态组件
-
函数组件又叫无状态组件,类组件又叫做有状态组件
-
状态{state} 即为数据
-
函数组件没有自己的状态,只负责数据展示(静),类组件相反
- state和setState
- state的值是对象,表示一个组件可以有多个数据
- this.setSate({要修改的值}) : 数据驱动视图
- 从jsx中抽离事件、改变this
class Hello extends React.Component {
constructor() {
super()
//初始化state
this.state = {
count: 0,
test: 'a',
}
//2改变this指向 Function.prototype.bind()
this.onIncrement = this.onIncrement.bind(this)
}
//3改变this指向 class的实例方法
onIncrement =() => {
//没办法直接用this.setState,
//改变this指向
//箭头函数、Function.prototype.bind()、class的实例方法-babel
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
<div>有状态组件,{this.state.count}</div>
<button onClick={() => {
this.setState({count: this.state.count + 1})
}}>第一种</button>
<button onClick={() => this.onIncrement}>第11种</button>
</div>
)
//1改变this指向 箭头函数
}
}
-
表单处理
-
受控组件
- 由state的值来控制表单元素的值
state = { txt: ''}
<input type="text" value = {this.state.txt}
onChange={e => this.setState({txt: e.target.value})}>
- 每个受控表单都有一个事件太过繁琐,使用统一事件处理程序
// 1. 给表单元素添加name属性,与state相同
// 2. 根据表单元素类型获取对应值
<input type="text" name="txt" value={this.state.txt} onChange={this.handleChange}/>
handleChange = e => {
//获取当前dom对象
const target = e.target
//根据类型获取值
const value = target.type === 'txt' ? target.value: ''
//获取name
const name = target.name
this.setState({
[name]: value
})
}
- 非受控组件
- 调用React.createRef()方法创建一个ref对象
- 将创建的ref对象添加到文本框中
- 通过ref对象获取到文本框的值
constructor(){
super()
this.txtRef = React.createRef()
}
<input type="text" ref={this.txtRef}/>
console.log(this.txtRef.current.value)