一、redux
工作流程:
首先,用户发出 Action。
store.dispatch(action);
然后,Store 自动调用 Reducer,并且传入两个参数:当前 State 和收到的 Action。 Reducer 会返回新的 State 。
let countReducer = (state = 0, action)=>{ switch(action.type) { case 'ADD': return state + 1; case 'MINUS': return state - 1; default: return state; } } const store = createStore(countReducer);
State 一旦有变化,Store 就会调用监听函数。
// 设置监听函数 store.subscribe(listener);
listener
可以通过store.getState()
得到当前状态。如果使用的是 React,这时可以触发重新渲染 View。
function listerner() { let newState = store.getState(); component.setState(newState); }
1.createStore(reducer):创建store,将reducer设置为参数
2.reducer = (state, action) => {} 初始化数据,修改状态函数
3.dispatch:提交更新
4.subscribe:订阅更新
5.getState:获取数据
例子:
store.js:
import { createStore } from "redux";
const CounterReducer = (state = 0, action) => {
switch (action.type) {
case "ADD":
return state + 1;
case "MINUS":
return state - 1;
default:
return state;
}
};
const store = createStore(CounterReducer);
export default store;
App.js:
import React, { Component } from "react";
import store from "./store";
class Api extends Component {
render() {
return (
<div>
<p>{store.getState()}</p>
<button onClick={() => store.dispatch({ type: "ADD" })}> + </button>
<button onClick={() => store.dispatch({ type: "MINUS" })}> - </button>
</div>
);
}
}
export default Api;
index.js:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import store from "./store.js";
const render = () => {
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
};
render();
// 订阅更新,重新渲染
store.subscribe(render);
二、react-redux
react-redux是连接react和redux 的桥梁,让react中使用redux时低耦合,方便快捷
react-redux
提供了两个
api
1. Provider
为后代组件提供
store
2. connect
为组件提供数据和变更⽅法
例子:
Index.js:
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import "./index.css";
import App from "./App";
import store from "./store.js";
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
App.js:
import React, { Component } from "react";
import { connect } from "react-redux";
class App extends Component {
render() {
const { num, dispatch, minus, add } = this.props;
return (
<div>
<p>{num}</p>
{/* <button onClick={() => dispatch({ type: "ADD" })}> + </button>
<button onClick={() => dispatch({ type: "MINUS" })}> - </button> */}
<button onClick={() => add({ type: "ADD" })}> + </button>
<button onClick={() => minus({ type: "MINUS" })}> - </button>
</div>
);
}
}
export default connect(
// 参数1将state映射到props
state => ({ num: state }),
// 参数2将dispatch映射到props,已经自动实现了
// 或者直接写
{
add: () => ({ type: "ADD" }),
minus: () => ({ type: "MINUS" })
}
)(App);
三、redux异步
1.引入中间件redux-thunk
2.createStore()第二个参数应用异步中间件
3.actions中执行异步操作(actions中同步返回一个对象,异步返回一个函数)
store.js:
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
const CounterReducer = (state = 0, action) => {
switch (action.type) {
case "ADD":
return state + 1;
case "MINUS":
return state - 1;
default:
return state;
}
};
// 应用异步中间件
const store = createStore(CounterReducer, applyMiddleware(thunk));
export default store;
App.js:
import React, { Component } from "react";
import { connect } from "react-redux";
class Api extends Component {
render() {
const { num, dispatch, minus, add, incrementAsync } = this.props;
return (
<div>
<p>{num}</p>
{/* <button onClick={() => dispatch({ type: "ADD" })}> + </button>
<button onClick={() => dispatch({ type: "MINUS" })}> - </button> */}
<button onClick={() => add()}> + </button>
<button onClick={() => minus()}> - </button>
<button onClick={() => incrementAsync()}> ASYNC </button>
</div>
);
}
}
// 同步返回一个对象
const add = () => ({ type: "ADD" });
const minus = () => ({ type: "MINUS" });
// 异步返回一个函数
const incrementAsync = () => {
return dispatch => {
// 异步代码
setTimeout(() => {
dispatch(add());
}, 1000);
};
};
export default connect(
// mapStateToProps将state映射到props
state => ({ num: state }),
// mapDispatchToProps将dispatch映射到props,已经自动实现了
// 或者直接写
{ add, minus, incrementAsync }
)(Api);
四、redux调试工具redux-devtools
1.chrome安装调试工具redux-devtools.crx,但一打开还不能使用,需要代码中引入redux-devtools-extension
2.安装redux-devtools-extension,在store.js中引入composeWithDevTools
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { composeWithDevTools } from "redux-devtools-extension";
const CounterReducer = (state = 0, action) => {
switch (action.type) {
case "ADD":
return state + 1;
case "MINUS":
return state - 1;
default:
return state;
}
};
const store = createStore(
CounterReducer,
// 应用异步中间件applyMiddleware(thunk)
// composeWithDevTools():使用redux-devtool调试工具
composeWithDevTools(applyMiddleware(thunk))
);
export default store;