Redux 重要API
Reducer 函数 就是根据旧的state返回新的state
const reducer = (state, action)=>{
if(state === undefined){
return {n: 0}
}else{
if(action.type === 'add'){
var newState = {n: state.n + action.payload}
return newState
}else{
return state
}
}
}
store
const store = createStore(reducer)
store.subscribe
store.subscribe(()=>{
render()
})
store.dispatch
store.dispatch({type:'add', payload: 1})
React-Redux
Provider 标签
<Provider store={store}>
<App />
</Provider>,
connect 函数
function mapStateToProps(state){
return {
n: state.n
}
}
function mapDispatchToProps(dispatch) {
return {
add1: ()=> dispatch({type:'add', payload: 1})
}
}
export default connect(mapStateToProps,mapDispatchToProps)(App);
简单例子
实现如图的简单功能
原生JS + Redux
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>hi redux</title>
</head>
<body>
<div id="app"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script>
function add1() {
store.dispatch({ type: "add", payload: 1 });
// dispatch 一个 action
// 触发一个事件
// 派发一个动作
}
function add2() {
store.dispatch({ type: "add", payload: 2 });
}
function addIf() {
let oldState = store.getState();
if (oldState % 2 === 1) {
store.dispatch({ type: "add", payload: 1 });
}
}
function addAsync() {
setTimeout(() => {
store.dispatch({ type: "add", payload: 1 });
}, 2000);
}
function render(store) {
const app = document.querySelector("#app");
app.innerHTML = `
<div>
你点击了 <span id="value">${store.getState()}</span>次
<div>
<button id="add1" onclick="add1()">+1</button>
<button id="add2" onclick="add2()">+2</button>
<button id="add1IfOdd" onclick="addIf()">如果是单数就+1</button>
<button id="add1After2Sec" onclick="addAsync()">两秒钟后+1</button>
</div>
</div>
`;
}
function stateChanger(state, action) {
if (state === undefined) {
return 0;
} else {
if (action.type === "add") {
let newState = state + action.payload;
return newState; //根据操作生成新的state 触发一个事件
} else {
return state;
}
}
}
let store = Redux.createStore(stateChanger);
render(store);
store.subscribe(() => {
render(store); // 接收到事件,重新render
});
</script>
</body>
</html>
store 存储了 state 想要获取state通过store.getState()
Redux + React
index.js
import React from "react";
import ReactDOM, { render } from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { createStore } from "redux";
const reducer = (state, action) => {
if (state === undefined) {
return 0;
} else {
if (action.type === "add") {
let newState = (state += action.payload);
return newState;
} else {
return state;
}
}
};
const store = createStore(reducer);
renders();
store.subscribe(() => {
renders();
});
function add3(){
if(store.getState() % 2 === 1){
store.dispatch({type:'add',payload:1})
}
}
function add4(){
setTimeout(()=>{
store.dispatch({type:'add',payload:1})
},2000)
}
function renders() {
ReactDOM.render(
<React.StrictMode>
<App
value={store.getState()}
onAdd1={() => {
store.dispatch({ type: "add", payload: 1 });
}}
onAdd2={() => {
store.dispatch({ type: "add", payload: 2 });
}}
onAdd3={add3}
onAdd4={add4}
/>
</React.StrictMode>,
document.getElementById("root")
);
}
reportWebVitals();
App.js
import React, { Component } from "react";
class App extends Component {
add1 = () => {
this.props.onAdd1()
}
add2 = () => {
this.props.onAdd2()
}
add3 = () => {
this.props.onAdd3()
}
add4 = () => {
this.props.onAdd4()
}
render() {
return (
<div>
你点击了 <span id="value">{this.props.value}</span>次
<div>
<button id="add1" onClick={this.add1}>+1</button>
<button id="add2" onClick={this.add2}>+2</button>
<button id="add1IfOdd" onClick={this.add3}>如果是单数就+1</button>
<button id="add1After2Sec" onClick={this.add4}>两秒钟后+1</button>
</div>
</div>
);
}
}
export default App;
Redux + React + React-Redux
- React-Redux可以让你随时访问stroe,而且不会混乱
- Provider会把store传给里面的每一个组件,并且会自动渲染
- connect是一个高阶函数,接收一个mapStateToProps参数也就是把全局的state映射到当前组件的props,必须是一个函数,第二个参数mapDispatchToProps,把dispatch映射到props,两种形式可以是个函数,也可以是个对象,还接收一个组件作为参数返回一个具有状态的组件
- connect会把这两个参数合并起来,作为props传给App
index.js
import React from "react";,
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { createStore } from "redux";
import { Provider } from "react-redux";
const reducer = (state, action) => {
if (state === undefined) {
return {n:0};
} else {
if (action.type === "add") {
let newState = {n: state.n + action.payload};
return newState;
} else {
return state;
}
}
};
const store = createStore(reducer);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
reportWebVitals();
App.js
import React, { Component } from "react";
import { connect } from "react-redux";
class App extends Component {
render() {
return (
<div>
你点击了 <span id="value">{this.props.n}</span>次
<div>
<button id="add1" onClick={() => this.props.add1()}>
+1
</button>
<button id="add2">+2</button>
<button id="add1IfOdd">如果是单数就+1</button>
<button id="add1After2Sec">两秒钟后+1</button>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
n: state.n,
};
}
function mapDispatchToProps(dispatch) {
return {
add1: () => dispatch({ type: "add", payload: 1 }),
};
}
export default connect(mapStateToProps, mapDispatchToProps )(App);