文章目录
前端之React学习(四)
路由进阶与高阶组件
高阶组件
参数是一个组件,同时返回的也是一个组件
这类组件称为高阶组件(如:WithRouter)
WithRouter
让不是路由切换的组件也具有路由切换组件的三个属性
- location
- match
- history
- 引用
- 运用
监控路由变化 history
history.listen((link)=>{
Link.pathname 切换路径
})
编程式导航 history
props.history.push("/xxx")
路由传参
params 方式传参 match
- 需要在路由规则中设置传递的接收参数
:xxx - 发送参数,直接在跳转路径后进行编写
- 接收参数 props.match.params
优势:
刷新地址,参数依然存在
缺点
只能传递字符串,并且参数过多的时后 url 变丑
query 方式传参 location
- 不需要在路由规则中进行参数的配置
- 直接发送参数
- 接收参数 this.props.location.query
hook
- 是 16.7 新增的特性
- 主要是用来让无状态组件可以使用状态,在 react 开发中状态的管理是必不可少的
- 以前为了进行状态管理,需要使用类组件或者 redux 等来管理
useState
- 引用
import {useState} from "react";
- 调用
useState 是定义一个状态,与类组件的状态不同,函数组件的状态可以是对象也可是基础数据类型
useState 返回的是一个数组,第一个是当前的状态值,第二个是对象(表面更改状态的函数)-----类似与 setState
function User(props) {
let [val, setVal] = useState(0);
return (
<div>
使用数据:{val}
<button
onClick={() => {
setVal(val + 1);
}}
>
点我进行数据修改
</button>
</div>
);
}
多个状态
声明对象类型的状态
多次声明(推荐)
//如果有多个状态?
//1. 声明对象类型状态
//2. 多次声明
function User(props) {
//1. 声明对象类型状态
// let [val, setVal] = useState({
// vala: 0,
// valb: 1,
// valc: 2,
// });
//多次声明(推荐)
let [cala, setVala] = useState(0);
let [calb, setValb] = useState(1);
let [calc, setValc] = useState(2);
return (
<div>
{/* <div>
对象声明使用数据:{val.vala}------{val.valb}-------{val.valc}
</div> */}
<div>
多次声明使用数据:{cala}-------{calb}-------{calc}
</div>
</div>
);
}
redux
redux 是 javascript 提供的一个可预测性的状态容器
我们给一个固定的输入,那么必定可以得到一个结果
集中管理 react 中的多个组件的状态
redux 是一个专门的状态管理库(vue 和 react 中都可使用)
需求场景
- 某个组件的状态需要共享的时候
- 一个组件需要改变另一个组件的状态的时候
- 组件中的状态需要在任何地方拿到的时候
三大原则
- 单一数据原则
整个 react 中的状态都会被统一管理到 store - state 是只读的
我们不能直接改变 state,而是要通过触发 redux 中特定的方法来进行修改 - 使用纯函数来执行修改操作
action 来改变 redux 中的 state
使用
下载
npm i --save redux
读取,修改
- 创建 redux 文件夹
- 在 redux 下 创建 reducer.js(设置 state 数据对象) store.js(接收,并导出需要的数据) action.js(修改 state 的操作函数)
- 在所需要 state 的组件中引用、渲染
- reduce.js
var obj = [{ name: "嘻嘻", age: 18 }];
export function data(state = obj[0].age, action) {
switch (action.type) {
case "ADD":
return state + action.data;
break;
case "DEL":
return state - action.data;
break;
default:
return state;
break;
}
}
- store.js
import { createStore } from "redux";
import { data } from "./reducer";
export var store = createStore(data);
- action.js
//增加
export const add = (num) => {
return { type: "ADD", data: num };
};
//减少
export const del = (num) => {
return { type: "DEL", data: num };
};
- home 组件
import React, { Component, Fragment } from "react";
//引用 store
import { store } from "../redux/store";
//引用action
import * as action from "../redux/action";
class Home extends Component {
constructor(props) {
super(props);
//读取数据
this.state = {
num: store.getState(),
};
}
componentDidMount() {
store.subscribe(() => {
this.setState({
num: store.getState(),
});
});
}
render() {
return (
<Fragment>
<div>home</div>
{this.state.num}
<button
onClick={() => {
store.dispatch(action.add(1));
}}
>
点我加1
</button>
<button
onClick={() => {
store.dispatch(action.del(1));
}}
>
点我减1
</button>
</Fragment>
);
}
}
export default Home;