一、React 路由
安装:npm install react-router-dom --save
ReactRouter三大组件:
Router:所有路由组件的根组件(底层组件),包裹路由规则的最外层容器。
Route:路由规则匹配组件,显示当前规则对应的组件
Link:路由跳转的组件
注意:如果要精确匹配,那么可以在route上设置exact属性。
二、Redux介绍
Redux 是 JavaScript 状态容器,提供项目中的状态管理。
redux的三个重要概念:
store: 数据仓库
action: 组件的动作名和动作的定义 (定义了如何修改仓库数据)
dispatch: 执行相应的动作action (执行修改的动作,决定了何时修改仓库数据)
Redux中提供createStore方法用于生成一个store对象,这个函数接受一个初始值state值和一个reducer函数。当用户发出相应的action时,利用传入的reducer函数计算出一个新的state值,并返回。
使用Redux,我们只获取一次数据并将其存储在一个中心位置,称为 store。然后,任何组件都可以随时使用这些数据。这就像附近有一家超市,我们的厨师可以在那里买到所有的食材。这家超市派卡车从农场大批运回蔬菜和肉类。这比让个别厨师亲自去农场效率高得多。
store 还是唯一的数据源。组件通常从 store 中获取数据,而不是其他地方。这使得 UI 保持高度统一。
注意:
Redux 不只是为 React 而生。一个常见的误解是 Redux 仅用于 React。 听起来Redux在没有React的情况下无法做任何事情。 事实上,正如我们之前所讨论的,Redux在几个重要方面补充了React。 React 是最最常见的 Redux 用例。
然而,事实上,Redux可以使用任何前端框架,如Angular、Ember.js 甚至jQuery 或者 普通的JavaScript。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nMSTxfEL-1598271184361)(C:\Users\Lenovo\Desktop\timg.jpg)]
下面看一个redux代码:
(前提:先安装redux yarn add redux 或者 npm install redux)
/*
redux小案例:
*/
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
import {createStore} from 'redux'
// 请一个仓库管理员,必须是一个函数
const reducer = (state, action) => {
console.log("执行了reducer函数")
console.log(state, action)
// 7、回到reducer函数,深拷贝action对象到newState,并返回
//(此时只是reducer中的参数state发生了变化,而视图组件中的state没有改变,第8步将处理组件中的state)
if(action.type === "up"){
let newState = JSON.parse(JSON.stringify(state))//深度拷贝
newState.num1 = action.value
return newState
}
// 1、定义初始state
return {
num1: 0
}
}
//创建一个仓库, 把仓库管理员请来管理这个仓库
// 2、创建store仓库
const store = createStore(reducer)
export default class App extends Component {
constructor(props){
super(props)
// console.log(store.getState())
// 3、在constructor中,获取初始state
this.state = store.getState()
this.changeNumUp = this.changeNumUp.bind(this)
// 8、store订阅(监听store里的数据是否发生变化),一旦store数据发生改变,则执行storeChange函数里面的代码
this.storeChange = this.storeChange.bind(this)
store.subscribe(this.storeChange)
}
render() {
return (
<div >
{/* 4、 书写组件,填入数据 */}
<p>{this.state.num1} </p>
{/* 5、业务:点击让num1自增 */}
<button onClick={this.changeNumUp}>增加</button>
</div>
)
}
changeNumUp(e){
// 6、改变数据的时候 需要调用store的dispatch方法,把新的值作为放在对象中传进去
// 每次调用dispatch, 会在内部调用 图书管理员函数reducer
const action = {
type:'up',
value:this.state.num1+1
}
store.dispatch(action) // 每次调用dispatch, 会在内部调用 图书管理员函数reducer
}
storeChange(e){
this.setState(store.getState())
}
}
ReactDOM.render(
<App />
, document.getElementById('root'));
三、React-Redux
为了方便使用,Redux 的作者封装了一个 React 专用的库 React-Redux。这个库是可以选用的。实际项目中,你应该权衡一下,是直接使用 Redux,还是使用 React-Redux。后者虽然提供了便利,但是需要掌握额外的 API,并且要遵守它的组件拆分规范。
React-Redux 将所有组件分成两大类:UI 组件(presentational component)和容器组件(container component)。
3.1、UI组件
UI 组件特征:
- 只负责 UI 的呈现,不带有任何业务逻辑
- 没有状态(即不使用
this.state
这个变量) - 所有数据都由参数(
this.props
)提供 - 不使用任何 Redux 的 API
3.2、容器组件
容器组件特征:
- 负责管理数据和业务逻辑,不负责 UI 的呈现
- 带有内部状态
- 使用 Redux 的 API
3.3、connect()
React-Redux 提供connect
方法,用于从 UI 组件生成容器组件。connect
的意思,就是将这两种组件连起来。
3.4、Provider组件
React-Redux 提供Provider
组件,可以让容器组件拿到state
状态数据。Provider
包裹了原来项目的根组件。
运行案例前先安装react-redux: **yarn add react-redux 或者 ** npm install react-redux
项目中使用react-redux
在App2.js中:
import React, { Component } from 'react'
import { connect } from 'react-redux'
class App2 extends Component {
render() {
return (
<div style="">
<p>{this.props.myNum}</p>
{/* 2、书写点击事件 ,要在以前的this后面加多.props*/}
<button onClick={this.props.handelClick.bind(this)}>增加</button>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
myNum: state.num1
}
}
// 1、事件写在mapDispatchToProps函数中
const mapDispatchToProps = (dispatch) => {
return {
handelClick(e){
//3、 调用dispatch(action),将管理状态的方案传当做参数
let action = {
type:'up',
//这里其实修改的是props中的myNum
value:this.props.myNum+1
}
dispatch(action)
}
}
}
// connect(展示数据的函数,改变数据的函数)(组件类名)
export default connect(mapStateToProps,mapDispatchToProps)(App2)
Base2.js组件中
/*
react-redux基础7 改变状态
*/
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
import {createStore} from 'redux'
import { Provider } from 'react-redux'
import App2 from "./App2"
const defaultState = {
num1: 0
}
// 请一个仓库管理员,必须是一个函数
const reducer = (state = defaultState, action) => {
if(action.type === "up"){
let newState = JSON.parse(JSON.stringify(state))
newState.num1 = action.value
return newState
}
return state
}
//创建一个仓库, 把仓库管理员请来管理这个仓库
const store = createStore(reducer)
const App = (
<Provider store={store}>
<App2 />
</Provider>
)
ReactDOM.render(
App
, document.getElementById('root'));
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vp1uLJmW-1598271184365)(C:\Users\Lenovo\Desktop\QQ截图20200716215832.png)]
四、前后台交互 ajax
下载依赖包yarn add axios或者 npm install axios
执行get请求
// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 可选地,上面的请求可以这样做
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
执行post请求
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
);
})
.catch(function (error) {
console.log(error);
});
执行post请求
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});