redux是一个状态管理插件,实现跨组件之间数据共享
其中redux遵循单项数据流的机制,在view视图中通过dispatch派发一个action改变数据,数据改变之后组件重新渲染。
appReducer接受两个参数一个是state一个是action,其中通过使用createStore来实现跨组件传参。
其中appReducer函数和createStore方法的使用如下:
import { createStore } from "redux";
/**
* @param {*} appReducer 接受两个参数
* @param {*} state
* @param {*} action
* @returns
*/
function appReducer(state = { count: 1, name: "Demo" }, action) {
// console.log();
switch (action.type) {
case "PLUS":
return {
...state,
count: state.count + action.payload,
name: action.name,
};
case "Test":
return {
...state,
count: state.count + action.payload,
};
default:
return { ...state };
}
/**
* @param {*} 改变数据
*/
}
const store = createStore(appReducer);
/**
* @param{dispatch派发}
*/
store.dispatch({
type: "PLUS",
payload: 1,
name: "测试",
});
store.dispatch({
type: "Test",
payload: 10,
});
export default store;
通过Provider进行redux和react的项目关联,代码如下图:
import store from "./store/index";
//Provider组件的作用是实现redux数据和react项目关联
import { Provider } from "react-redux";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
在app.jsx中,可以通过使用connect(高阶组件)的方法把redux的数据映射到组件上,redux数据如图一代码:其中connect映射使用的过程如下:
import { connect } from "react-redux"; //connect 把redux数据映射到组件上
import Counter from "./components/Counter";
function App(props) {
console.log(props, "props");
return (
<div>
<h1>{props.count}</h1>
<Counter />
</div>
);
}
const mapStateToProps = (state) => state;
export default connect(mapStateToProps)(App);
在组件中可以通过dispatch派发来改变redux数据,跨组件之间传参!代码如下图
import React from "react";
import { connect } from "react-redux";
function Counter(props) {
const changeBtnValue = () => props.dispatch({ type: "PLUS", payload: 1 });
return (
<div>
{/* <button onClick={() => props.dispatch({ type: "PLUS", payload: 2 })}>
{props.count}
</button> */}
<button onClick={() => changeBtnValue()}>{props.count}</button>
</div>
);
}
export default connect((state) => state)(Counter);
此方法有点老,纯属是为了后续学习useSelector和useDispatch做铺垫!!
----------------------------------------------------持续更新
当数据过多的时候,可以创建一个reducer文件夹,把所需数据放进去:
export default function listReducer(
state = { page: 1, data: [], total: 0 },
action
) {
return state;
}
-------------------
export default function personReducer(
state = { name: "", skill: "", desc: "" },
action
) {
return state;
}
-------------------
export default function appReducer(state = { count: 1, name: "Demo" }, action) {
// console.log();
switch (action.type) {
case "PLUS":
return {
...state,
count: state.count + action.payload,
name: action.name,
};
case "Test":
return {
...state,
count: state.count + action.payload,
};
default:
return { ...state };
}
}
通过使用combineReducers方法把所需数据放入一个对象里面进行调用。
import { createStore, combineReducers } from "redux";
import app from "./reducer/app";
import list from "./reducer/list";
import person from "./reducer/person";
const rootReducer = combineReducers({ app, list, person });
const store = createStore(rootReducer);
export default store;
在使用过程中,调取对象中的属性获取redux中的数据对象信息。
import { connect } from "react-redux"; //connect 把redux数据映射到组件上
import Counter from "./components/Counter";
function App(props) {
console.log(props, "props");
return (
<div>
<h1>{props.count}</h1>
<Counter />
</div>
);
}
const mapStateToProps = (state) => state.app;
export default connect(mapStateToProps)(App);
其中在组件中使用useSelector和useDispatch两种方法对数据进行改变
import React from "react";
/**
* @param useSelector获取redux中的数据
*/
import { connect, useSelector, useDispatch } from "react-redux";
import { addAction } from "../store/actions/app";
function Counter(props) {
const s = useSelector((state) => state.list);
console.log(s, "s");
/**
* @useDispatch 可以获取dispatch方法
*/
const dispatch = useDispatch();
return (
<div>
<button onClick={() => dispatch({ type: "PLUS", payload: s.page })}>
{props.count}
</button>
{/* 引入封装好的action */}
<button onClick={() => dispatch(addAction(8))}>{props.count}</button>
</div>
);
}
export default connect((state) => state.app)(Counter);
其中需要知道的面试重点:
1.action中type为什么不能重复?
因为每一次派发的时候每一个reducer都会接收到这个action,为了区分怎么改变数据,所以action中的type不能重复。
可以使用symbol这个数据类型或者每一个action的type设置前缀。
action必须是一个简单的对象,不能是异步的。如果需要处理异步action,需要安装中间键redux-thunk。
2.单向数据流以及redux的数据流向。