React
JavaScript基础
设置定时器:this.timer = setInterval(() => {}, xxx)
清除定时器:clearInterval(this.timer)
setTimeout(() => { xxx }, 2000) //2秒后做
React 特性
-
引入React
-
jsx
{}里写js表达式(有返回值的表达式)
style={{key:“value”}}
className=“title” -
函数式组件:
1、首字母大写
2、组件引用闭合
3、三大组件只有props -
类式组件:
1、extends React.Component
2、render() //rander是类的一种方法
3、返回值
类中可以定义:构造器,自定义方法,赋值语句 -
构造器
super(props)//不写props的话无法通过this.props取值
this.state={}//给状态赋初值
this.changeWeather=this.changeWeather.bind(this)//为事件处理函数绑定实例 -
state:
初始化状态 : state={xx:xx, xx:xx}//类里写,给实例幅值
自定义方法 : xx = ()=>{}
onClick={xxx}
设置state : this.setState({xx:xx})
.bind()返回一个新函数 -
props:
1、<Person name=“dongfang” age=“18” >
2、限制属性
static propTypes = {
name:PropTypes.string.isRequired,
}
3、设置默认属性值
static defaultProps = {
sex:“男”
}
2和3需要导入包prop-types -
refs
1、ref={c => this.input = c}
2、
myRef = React.createRef()
ref = {this.myRef} -
事件处理
通过onXxx属性指定事件处理函数
event.target.value -
收集表单数据
render() { return( <form action=“”> </form> )} -
高阶函数
1.若A函数,接受的参数是一个函数,那么A为高阶函数
2.若A函数,调用的返回值是一个函数,那么A为高阶函数
函数的柯里化
通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码方式
React 组件的生命周期
render:初始化渲染,状态更新之后调用
componentDidMount( ){ }:组件挂载后调用
componentWillUnmount( ){ }:组件将要卸载
ReactDOM.unmountComponentAtNode(document.getElementById(“test”)):卸载组件
旧生命周期
挂载时:
constructor -> will mount -> render -> mount -> will unmount
constructor() -> componentWillMount() -> render() -> componentDidMount() -> componentWillUnmount()
setState:
shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate -> will unmount
forceUpdate:
componentWillUpdate -> render -> componentDidUpdate -> will unmount
父组件render:
componentWillReceiveProps + setState的生命周期
新生命周期
可以用旧钩子(最好不要)
getDerivedStateFromProps
state 取决于 props
static getDerivedStateFromProps( ) { return }
getSnapshotBeforeUpdate
getSnapshotBeforeUpdate( ) { return }
diffing算法
React 脚手架
脚手架:模块化,组件化,工程化
安装Node
官网下载并安装node
查看版本node -v
npm --version
更改配置:npm config set prefix "E:\node\node_global"
npm config set cache "E:\node\node_cache"
添加环境变量:
sys-path E:\node\node_global\node_modules
E:\node\node_global
user-path C:\Users\79312\AppData\Roaming\npm
E:\node\node_global
创建React项目
npm install -g create-react-app
create-react-app xxx
yarn start
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<!-- 移动端适配 -->
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- 浏览器页签的颜色 -->
<meta name="theme-color" content="#000000" />
<!-- 描述网站信息 -->
<meta
name="description"
content="Web site created using create-react-app"
/>
<!-- 添加网页到主屏幕时的图标 -->
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!-- 配置移动端的文件 -->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
</head>
<body>
<!-- 不支持js时的显示 -->
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
React Ajax
前端需要通过Ajax请求与后台交互
常用Ajax请求库:
- jQuery(不可用)
- axios
axios
yarn add axios
- 封装了XmlHttpRequest
- promise风格
- 可用于浏览器、node服务器
跨域代理
setupProxy.js
const {createProxyMiddleware} = require('http-proxy-middleware')
const proxy = require('http-proxy-middleware')
module.exports = function(app) {
app.use(
createProxyMiddleware('/api1/students',{
target:'http://localhost:5000',
changeOrigin:true,
pathRewrite:{'^/api1':''}
}),
createProxyMiddleware('/api2',{
target:'http://localhost:5001',
changeOrigin:true,
pathRewrite:{'^/api2':''}
})
)
}
消息订阅—发布机制
yarn add pubsub-js
import PubSub from 'pubsub-js'
//订阅
this.token = PubSub.subscribe('Topic',(msg,data)=>{
console.log(data);
})
//发布
PubSub.publish('Topic',{name:'dongfang',age:18})
//取消订阅
PubSub.unsubscribe(this.token)
Fetch
外层函数加 async
const response = await fetch('url')
const data = await response.json()
React 路由
SPA应用
- 单页web应用
- 局部刷新
- ajax请求获取数据,前端一展现
路由
key 为路径,value为 function 或 component
两种history
- BrowserHistory
- HashHistory
React-Router-DOM(Web路由组件)
React-Router:
- web(React-Router-DOM)
- native
- anywhere
安装
yarn add react-router-dom
version6
npm i react-router-dom@5
version5
使用
<BrowserRouter>
编写路由链接---实现切换组件
<Link className="" to="/about">about</Link>
<Link className="" to="/home">home</Link>
高亮
<NavLink activeClassName="" className="" to="/about">about</NavLink>
注册路由
<Route path="/about" component={About} />
<Route path="/home" component={Home} />
路由组件接收的props:history location match
</BroserRouter>
Switch:路径遍历到即停止
<Switch>
<Route path="/about" component={About} />
<Route path="/home" component={Home} />
<Redirect to="/about" />
</Switch>
1.向路由组件传递params参数
<BrowserRouter>
<Link to={`/about/detail/${id}/${title}`}>about</Link>
<Route path="/about/detail/:id/:title" component={About} />
</BroserRouter>
接收:this.props.match.params
2.向路由组件传递search参数
<BrowserRouter>urlencoded:name=dong&age=18
<Link to={`/about/detail/?id=${id}&title=${title}`}>about</Link>
<Route path="/about/detail" component={About} />
</BroserRouter>
接收:this.props.location
3.向路由组件传递search参数
<BrowserRouter>
<Link to={{pathname:"/about/detail",state:{id:xxx,title:xxx}}}>about</Link>
<Route path="/about/detail" component={About} />
</BroserRouter>
接收:this.props.location.state || {}
replace模式
<Link replace="true" to="/about">about</Link>
编程式路由导航
路由组件:(一般组件不能用)
this.props.history.replace(url, {a:xxx,b:xxx})
this.props.history.push()
this.props.history.goForward(1)//前进一步
this.props.history.goBack(2)//后退两步
将一般组件转为路由组件:
export default withRoiuter(Header);
Ant-Design
yarn add antd
然后看官网
Redux
yarn add redux
Redux:状态管理的JS库
组件的状态共享(共享)
组件改变另一个组件的状态(通信)
(能不用就不用)
Action
dispatch(action)
type
data
Store
Reducers
项目打包运行
安装serve:npm i serve -g
serve
以当前目录为根目录运行服务器
Hooks
node-16.8 以后
-
state hook
const [xxx, setxxx] = useState()
-
effect hook
useEffect(() => { xxx }, [监听目标])
-
ref hook
const myRef = useRef()
ref = {myRef}
扩展
Fragment:<Fragment> </Fragment>
Context:
1.创建全文context
const MyContext = React.createContext()
2.提供者
<MyContext.Provider value={}>
<子组件/>
</MyContext.Provider>
3.使用者(声明需要)
static contextType = MyContext
使用
{this.context}
3.使用者(函数式组件)
<MyContext.Consumer>
{
value => ()
}
</MyContext.Consumer>