文章目录
React 学习
官网:https://react.docschina.org/
用于构建用户界面的 JavaScript 库
虚拟 DOM
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="test"></div>
<div id="test1"></div>
<div id="test2"></div>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/babel.min.js"></script>
<script type="text/javascript">
const msg = 'Promise Me'
const myId = 'Ta'
// 转为小写 转为大写
const vDom1 = React.createElement('h2', { id: myId.toLowerCase() }, msg.toUpperCase())
ReactDOM.render(vDom1, document.getElementById('test1'))
</script>
<script type="text/babel">
// 创建虚拟 DOM 元素对象
let vDom = <h1>hh</h1>// 不是字符串
// 将虚拟 DOM 渲染到页面真实 DOM 容器中
ReactDOM.render(vDom, document.getElementById('test'))
// 创建虚拟 DOM 元素对象
const vDom2 = <h3 id={myId.toUpperCase()}>{msg.toLowerCase()}</h3>
// 将虚拟 DOM 渲染到页面真实 DOM 容器中
ReactDOM.render(vDom2, document.getElementById('test2'))
</script>
</body>
</html>
效果图
jsx
React 面向组件编程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="temp"></div>
<div id="component"></div>
<div id="component1"></div>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/babel.min.js"></script>
<script type="text/babel">
// 数组遍历
const names = ['jQuery', 'vue', 'react']
// 创建虚拟 DOM 元素对象
const ul = (<ul>{names.map((name, index) => <li key={index}>{name}</li>)}</ul>)
// 将虚拟 DOM 渲染到页面真实 DOM 容器中
ReactDOM.render(ul, document.getElementById('temp'))
// 组件
function MyComponentGuo() {
return <p>GG</p>
}
class MyComponent extends React.Component {
render() {
return <p>jj</p>
}
}
// 将虚拟 DOM 渲染到页面真实 DOM 容器中
ReactDOM.render(<MyComponentGuo />, document.getElementById('component'))
ReactDOM.render(<MyComponent />, document.getElementById('component1'))
</script>
</body>
</html>
效果图
组件三大属性
state
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="like"></div>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/babel.min.js"></script>
<script type="text/babel">
// 组件三大属性——state
class Like extends React.Component {
constructor(props) {
super(props)
// 初始化状态
this.state = { isLikeMe: true }
// 将新增方法中的 this 强制绑定为组件对象
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
// 得到状态并取反
const isLikeMe = !this.state.isLikeMe
// 更新状态
this.setState({ isLikeMe })
}
render() {
// 读取状态
const { isLikeMe } = this.state
// 点击事件
return <h2 onClick={this.handleClick}>{isLikeMe ? '1' : '2'}</h2>
}
}
ReactDOM.render(<Like />, document.getElementById('like'))
</script>
</body>
</html>
效果图
props
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="person"></div>
<div id="person1"></div>
<div id="person2"></div>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/prop-types.js"></script>
<script src="./js/babel.min.js"></script>
<script type="text/babel">
// 组件三大属性——props
// function Person(props) {
// return (
// <ul>
// <li>姓名:{props.name}</li>
// <li>年龄:{props.age}</li>
// <li>性别:{props.sex}</li>
// </ul>
// )
// }
class Person extends React.Component {
render() {
return (
<ul>
<li>姓名:{this.props.name}</li>
<li>年龄:{this.props.age}</li>
<li>性别:{this.props.sex}</li>
</ul>
)
}
}
// 指定属性默认值
Person.defaultProps = {
sex: '男',
age: 18
}
// 指定属性值的类型和必要性
Person.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number
}
const p1 = {
name: 'qq',
age: 20,
sex: 'nan'
}
ReactDOM.render(<Person name={p1.name} age={p1.age} sex={p1.sex} />, document.getElementById('person'))
// 展开运算符
ReactDOM.render(<Person {...p1} />, document.getElementById('person1'))
const p2 = { name: 'ww' }
ReactDOM.render(<Person name={p2.name} />, document.getElementById('person2'))
</script>
</body>
</html>
效果图
ref
功能界面的组件化编码流程
- 拆分组件,抽取组件
- 实现静态组件:使用组件实现静态页面效果
- 实现动态组件:动态显示初始化数据;交互功能
组件化编码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/prop-types.js"></script>
<script src="./js/babel.min.js"></script>
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props)
// 初始化状态
this.state = { todos: ['1', '2', '3', '4'] }
this.addTodo = this.addTodo.bind(this)
}
addTodo(todo) {
const { todos } = this.state
todos.unshift(todo)
// 更新状态
this.setState({ todos })
}
render() {
const { todos } = this.state
return (
<div>
<h1>List</h1>
<Add count={todos.length} addTodo={this.addTodo} />
<List todos={todos} />
</div>
)
}
}
class Add extends React.Component {
constructor(props) {
super(props)
this.add = this.add.bind(this)
}
add() {
// 读取输入的数据
const todo = this.todoInput.value.trim()
// 检查合法性
if (!todo) {
return
}
// 添加
this.props.addTodo(todo)
// 清除输入
this.todoInput.value = ''
}
render() {
return (
<div>
<input type="text" ref={input => this.todoInput = input} />
<button onClick={this.add}>add #{this.props.count + 1}</button>
</div>
)
}
}
Add.propTypes = {
count: PropTypes.number.isRequired,
addTodo: PropTypes.func.isRequired
}
class List extends React.Component {
render() {
const { todos } = this.props
return (
<div>
<ul>
{todos.map((todo, index) => { return <li key={index}>{todo}</li> })}
</ul>
</div>
)
}
}
List.propTypes = {
todos: PropTypes.array.isRequired
}
ReactDOM.render(<App />, document.getElementById('app'))
</script>
</body>
</html>
效果图
受控组件与非受控组件
获取表单数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="login"></div>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/prop-types.js"></script>
<script src="./js/babel.min.js"></script>
<script type="text/babel">
class LoginForm extends React.Component {
constructor(props) {
super(props)
// 初始化状态
this.state = { pwd: '' }
this.handleSubmit = this.handleSubmit.bind(this)
this.handleChange = this.handleChange.bind(this)
}
handleSubmit(event) {
const name = this.nameInput.value
const { pwd } = this.state
alert(`用户名为:${name},密码为:${pwd}`)
// 阻止事件的默认行为(提交)
event.preventDefault()
}
handleChange(event) {
// 读取输入的值
const pwd = event.target.value
// 更新 pwd 的状态
this.setState({ pwd })
}
render() {
return (
<form action="/test" onSubmit={this.handleSubmit}>
用户名:<input type="text" ref={input => this.nameInput = input} />
密码:<input type="password" value={this.state.pwd} onChange={this.handleChange} />
<input type="submit" value="登录" />
</form>
)
}
}
ReactDOM.render(<LoginForm />, document.getElementById('login'))
</script>
</body>
</html>
生命周期
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="life"></div>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/prop-types.js"></script>
<script src="./js/babel.min.js"></script>
<script type="text/babel">
// 生命周期
class Life extends React.Component {
constructor(props) {
super(props)
// 初始化状态
this.state = { opacity: 1 }
}
distroyComponent() {
ReactDOM.unmountComponentAtNode(document.getElementById('life'))
}
componentDidMount() {
// 循环定时器
this.intervalId = setInterval(function () {
let { opacity } = this.state
opacity -= 0.1
if (opacity <= 0) {
opacity = 1
}
this.setState({ opacity })
}.bind(this), 200);
}
componentWillUnmount() {
// 清理定时器
clearInterval(this.intervalId)
}
render() {
const { opacity } = this.state
return (
<div>
<h2 style={{ opacity: opacity }}>{this.props.msg}</h2>
<button onClick={this.distroyComponent}>buhuole</button>
</div>
)
}
}
ReactDOM.render(<Life msg='react' />, document.getElementById('life'))
</script>
</body>
</html>
componentWillReceiveProps:
https://www.jianshu.com/p/aa1ec0eaded4
获取当前时间
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="hello"></div>
<script src="./js/react.development.js"></script>
<script src="./js/react-dom.development.js"></script>
<script src="./js/prop-types.js"></script>
<script src="./js/babel.min.js"></script>
<script type="text/babel">
class Hello extends React.Component {
constructor(props) {
super(props)
this.state = {
date: new Date()
}
}
componentDidMount() {
setInterval(() => {
this.setState({
date: new Date()
})
}, 1000);
}
render() {
return (
<p>
hello,<input type="text" placeholder='your name here ' />
<span>it is {this.state.date.toTimeString()}</span>
</p>
)
}
}
ReactDOM.render(<Hello />, document.getElementById('hello'))
</script>
</body>
</html>
React 脚手架
全局下载 React 脚手架:npm i -g create-react-app
创建一个名为 react_app 的项目文件夹:create-react-app react_app
如果遇到错误,参照:https://blog.csdn.net/zsl15039718107/article/details/104128166
切换到项目文件夹:cd react_app
运行并初始化项目:npm start
react ajax
React 本身只关注于界面,并不包含发送 ajax 请求的代码
前端应用需要通过 ajax 请求与后台进行交互(json 数据)
axios
- 封装 XmlHttpRequest 对象的 ajax
- promise
- 可以用在浏览器端和 node 服务器端
组件间通信
- 通过 props 传递
- 使用消息订阅(subscribe)-发布(publish)机制
- redux
react-router
react 的一个插件库
专门用来实现一个 SPA 应用
基于 react 的项目基本都会用到此库
SPA
单页 Web 应用
整个应用只有一个完整的页面
点击页面中的链接不会刷新页面,本身也不会向服务器发请求
当点击链接时,只会做页面的局部更新
数据都需要通过 ajax 请求获取,并在前端异步展现
路由
一个路由就是一个映射关系(key:value)
key 为路由路径,value 可能是 function/component
react-ui
material-ui(国外)
ant-design(国内)https://ant.design/index-cn
redux
https://www.cntofu.com/book/4/readme.html
一个独立专门用于做状态管理的 JS 库(不是 react 插件库)
它可以用在 react,angular,vue 等项目中,但基本与 react 配合使用
集中式管理 react 应用中多个组件共享的状态
action
reducer
store