react快速入门
react是什么?
- 一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库
- 使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”
- 简而言之就是一个将我们页面组装框架,它方便了我们代码重用
- 它使用jsx语法来帮我们构建页面,帮我们规范化每个组件的功能
- react可以实现动态渲染,实现数据实时动态更新
什么是jsx
- 在js中可以输出类似xml结构的数据,类似html这种
构建本地环境
- 前提:确保安装了nodejs,npm
- 构建react应用
[~]# npx create-react-app demo
[~]# cd demo
README.md node_modules package-lock.json package.json public src
[~]# npm start # 可以查看是否可以正常访问
react界面UI库
- 安装
npm install antd --save
react路由控制
- 安装
npm install --save react-router
项目结构
- package.json: 包含了我们的依赖包版本说明等
- src/index.js: 是程序的主入口文件,所有的模板渲染从这里开始
- src/index.css: 包含了渲染样式
- src/App.js: 是程序组件化封装的地方
如果构建简单应用,则在App.js中添加即可
如果构建复杂应用,则建议新建组件目录,App.js仅仅负责组装组件页面
react核心知识
组件挂载与渲染
- 方式
import ReactDOM from 'react-dom';
const App = <h1>App</h1>
ReactDOM.render(
(<App />),
document.getElementById('root')
)
- 原理
在react中, 页面的渲染通过构建虚拟Dom树, 当有数据更新时,仅仅需要更新某一个节点以下的节点即可,这种渲染方式提升了性能
JSX特性
- 样例
const App = <h1>App</h1>
- 说明
JSX表示使用xml格式来表示Dom树,在JSX中使用{}来传递变量值
组件与数据传递
- 方式
// function
function App(props){
// props是数据传递通道,由父组件传递,组件之间通信的工具
return <h1>App {props.info}</h1>
}
<App info="hello"/>
import React from 'react';
// class
class App extends React.Component{
constructor(props) {
super(props);
// props是数据传递通道,由父组件传递,组件之间通信的工具
}
render() {
return <h1>App {this.props.info}</h1>
}
}
<App info="hello"/>
数据更新与元素渲染
import React from 'react';
// class
class App extends React.Component{
constructor(props) {
super(props);
this.date = {
date: new Data()
}
}
render() {
return <h1>App {this.props.info}</h1>
}
}
state与生命周期
- 生命周期在react中以class展现,必须继承React.Component
- 但是官方不推荐使用class,而是推荐是用function的Hook方式
- 目前大多的框架组件都采用Hook方式
import React from 'react';
class A extends React.Component {
constructor(props) {
super(props);
this.state = {
date: new Date() // 定义时间对象变量,该变量在类中均可使用,在该变量发生更新时,本节点元素重新渲染
}
}
fresh_time() {
// 修改this.state, 更新是异步的
this.setState(
{ date: new Date() }
)
}
componentDidMount() {
// 当组件被挂载时,执行的方法
// 挂载成功时,我们设置一个定时器,让其修改变量state.date, 以实现页面动态渲染
this.time_interval = setInterval(
() => this.fresh_time(), 1000
)
}
componentWillUnmount() {
// 当组件被卸载时,执行的方法
clearInterval(this.time_interval) // 当组件卸载时,将定时器清除掉
}
render() {
return (
<p>现在时间是 {this.state.date.toLocaleTimeString()}</p>
)
}
}
事件处理
- react事件采用小驼峰式(camelCase),而不是纯小写
- 例如 onClick,onChange
- class
import React from 'react';
class App extends React.Component {
constructor() {
super()
this.state = {
bool_value: true
}
}
handleClick = () => {
this.setState({
// 设置布尔值,将其取反
bool_value: !this.state.bool_value
})
console.log(this.state.bool_value)
}
render() {
return (
<div>
<button onClick={this.handleClick}>点我取反</button>
<p>当前布尔值:{this.state.bool_value.toString()}</p>
</div>
)
}
}
- Hook
import React, { useState } from "react";
function App() {
let [bool_value, setBoolValue] = useState(true)
const handleClick = () => {
// 设置布尔值,将其取反
setBoolValue(
bool_value = !bool_value
)
console.log(bool_value)
}
return (
<div>
<button onClick={handleClick}>点我取反</button>
<p>当前布尔值:{bool_value.toString()}</p>
</div>
)
}
条件渲染
function App() {
let [color, setColor] = useState("red")
function handleClick() {
if (color == "red") {
setColor(
color = "blue"
)
} else {
setColor(
color = "red"
)
}
}
return (
<div>
<button onClick={handleClick}>点我变字体颜色</button>
{/* 条件渲染,使用{}来实现,示例中使用了三目运算,也可以将该条件渲染,封装为函数,使用if...else...语句 */}
{color == "red" ? <p style={{ color: color }}>我是红色的字体</p> : <p style={{ color: color }}>我是蓝色字体</p>}
</div>
)
}
标记并访问Dom元素
function Main() {
let eleRef = React.createRef() // 用ref标记Dom元素,并应用它
let [textValue, setTextValue] = useState("")
function handleClick() {
console.log(eleRef.current)
console.log(eleRef.current.value)
setTextValue(textValue = eleRef.current.value)
}
function handleChange() {
setTextValue(textValue = eleRef.current.value)
}
return (
<div>
<input type="text" ref={eleRef} onClick={handleClick} onChange={handleChange}></input>
<p>{textValue}</p>
</div>
)
}
Context实现数据全局通信
- 数据动态更新方式有props,还可以使用Context来全局使用,避免多个组件数据传递props
let ColorContext = React.createContext("red") // 全局设置颜色控制器, 其他组件需要使用该变量值,则用Consumer来获取即可
function MyText() {
return (
// 从Context中取color值
<ColorContext.Consumer>
{
(color) =>
<div>
<p style={{ color: color }}>颜色控制</p>
</div>
}
</ColorContext.Consumer>
)
}
function Main() {
let [color, setColor] = useState("red")
function handleClick() {
if (color == "red") {
setColor(
color = "blue"
)
} else {
setColor(
color = "red"
)
}
}
return (
// 这里向Context中生产数据,当数据更新时,则子组件则同步更新
<ColorContext.Provider value={color}>
<button onClick={handleClick}>点我控制字体颜色</button>
<MyText></MyText>
</ColorContext.Provider>
)
}
Hook
- hook是为函数组件赋予与class一样的能力,例如数据传递等
function App() {
let [color, setColor] = useState("red") // 定义变量,返回变量值与修改变量值的方法
function handleClick() {
if (color == "red") {
setColor(
color = "blue"
)
} else {
setColor(
color = "red"
)
}
}
// useEffect 将在渲染后执行
useEffect(() => {
console.log(color)
})
return (
<div>
<button onClick={handleClick}>点我控制字体颜色</button>
{color}
</div>
)
}
react中使用静态检查
使用typescript来类型校验
- 在现有模板中应用tsx
npm install --save-dev typescript # 安装typescript
npm i --save-dev @types/react # 安装react的typescript支持
import React from 'react'
export function App() {
return (
<div>
你好
</div>
)
}
- 创建react-typescript项目
npx create-react-app my-app --template typescript
import React from 'react';
import logo from './logo.svg';
import './App.css';
interface Props {
name: string;
}
function Main(props:Props){
console.log(props)
return (
<div>
<p>我是 {props.name}</p>
</div>
)
}
function App() {
return (
<Main name="man"/>
);
}
export default App;
react第三方ui库
- 只需要参考文档引入antd中的组件即可
import React from 'react';
import { Button } from 'antd';
import './App.css';
const App = () => (
<div className="App">
<Button type="primary">Button</Button>
</div>
);
export default App;
react第三方路由库
- 以下案例是使用antd UI库以及react-router来构建的案例
export class SiderNav extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Menu
defaultSelectedKeys={["1"]}
// mode="inline"
theme="dark"
>
<Menu.Item key="1" icon={<PieChartOutlined />}>
<Link to="/us">关于我们</Link>
</Menu.Item>
<Menu.Item key="2" icon={<DesktopOutlined />}>
<Link to="/info">信息通知</Link>
</Menu.Item>
</Menu>
</div>
);
}
}
export class AboutUs extends React.Component {
render() {
return (
<div
className="site-layout-background"
style={{ padding: 24, minHeight: 360 }}
>
这里是关于我们
</div>
);
}
}
export class AboutInfo extends React.Component {
render() {
return (
<div
className="site-layout-background"
style={{ padding: 24, minHeight: 360 }}
>
详细信息
</div>
);
}
}
function App() {
return (
// v5
// <Router>
// {/* <div>nihai</div> */}
// <Route path="about" component={AboutUs} />
// <Route path="aboutnfo" component={AboutInfo} />
// </Router>
// v6
<div>
<Router>
<Layout style={{ minHeight: "100vh" }}>
<Sider collapsible>
<SiderNav></SiderNav>
</Sider>
<Layout>
<Header
className="site-layout-sub-header-background"
style={{ padding: 0 }}
/>
<Content style={{ margin: "24px 16px 0" }}>
<Routes>
<Route path="/" element={<AboutInfo />} />
<Route path="us" element={<AboutUs />} />
<Route path="info" element={<AboutInfo />} />
</Routes>
</Content>
<Footer style={{ textAlign: "center" }}>
Ant Design ©2018 Created by Ant UED
</Footer>
</Layout>
</Layout>
</Router>
</div>
);
}
export default App;