redux
状态管理工具,遵循的是单项数据流.
reducer是用来改变数据的
action是用来组织数据,每一个action需要包含一个type属性
state是用来存储数据的
如果要改变数据是通过dispatch派发一个action在reducer中改变数据
redux和vuex的区别:
vuex只能在vue中使用
redux可以和任何一个前端框架进行结合
命令安装
npm i redux # 安装依赖项
npm i react-redux # react和redux 关联结合使用
// 定义一个reducer
function counter(state, action) {
switch(action.type) {
case '':
return xxxx
....
default:
return state
....
}
}
store.js
import { createStore, combineReducers } from "redux";
// 定义reducer的时候它是一个function 接收两个参数
// 参数一 初始状态
// 参数二 action 表示以什么方式改变数据
function counter(state = { count: 1 }, action) {
console.group("counter reducer");
console.log(state);
console.log(action);
console.groupEnd();
/* action.type的值必须是唯一的,不可以重复 */
switch (action.type) {
case "ADD":
return { ...state, count: state.count + action.payload.step };
default:
return state;
}
}
function product(state = { list: [], page: 1 }, action) {
console.group("product reducer");
console.log(state);
console.log(action);
console.groupEnd();
switch (action.type) {
/* case value:
break; */
default:
return state;
}
}
const lastReducer = combineReducers({
/* 属性名:属性值,其中属性名可以改变 */
counter: counter,
product: product,
});
const store = createStore(
lastReducer,
// 截图有步骤
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
); // 创建一个store
// 初始化加载
console.log(store.getState());
store.dispatch({
type: "ADD",
payload: {
step: 3,
},
});
console.log(store.getState());
export default store;
App.js
import React from "react";
import { connect } from "react-redux";
import Counter from "./components/Counter";
import "./App.css";
function App(props) {
console.log(props);
/* const {
counter: { count,dispatch },
} = props; */
const { count, dispatch } = props;
return (
<div className="App">
<h1>{count}</h1>
<button
onClick={() =>
dispatch({
type: "ADD",
payload: {
step: 2,
},
})
}
>
加
</button>
<Counter />
</div>
);
}
// state表示所有的数据
/* 1️⃣function mapStateToProps(state) {
// return state;
return state.counter;
}
export default connect(mapStateToProps)(App); */
// 通过connect可以把redux中的state数据和dispatch方法映射到组件的属性中
// 2️⃣等价1️⃣
export default connect((state) => state.counter)(App);
index.js
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import store from "./store";
ReactDOM.render(
<React.StrictMode>
{/* Provider提供一个东西叫store,即第一个store是Provider的一个属性名,而第二个store是一个引入过来的变量名,写好之后就会在整个组件最外层提供一个数据, */}
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
Counter.jsx
import React from "react";
import { connect } from "react-redux"; // 获取redux的数据
export const Counter = (props) => {
console.log(props);
return (
<div>
<h5>{props.count}</h5>
</div>
);
};
const mapStateToProps = (state) => ({
count: state.counter.count, // 这里返回的是什么,props里就有什么
});
export default connect(mapStateToProps)(Counter);