语法
一、redux 同步
二、redux 异步
三、redux legacy 同步
-
Redux
每一次state
更新,都会重新render
,大型应用中会造成不必要的重复渲染 -
Redux
只是个纯粹的状态管理器,默认只⽀持同步,实现异步任务 ⽐如延迟,⽹络请求,需要中间件的⽀持
1. 安装redux
yarn add redux -S
2. store --> index.js
用于创建Store
import { createStore, combineReducers } from "redux";
import { countReducer, usernameReducer } from "./reducer";
const reducer = combineReducers({
count:countReducer,
username:usernameReducer
});
const store = createStore(reducer)
export default store;
3. store --> reducer.js
用于统一维护Reducer
export const countReducer = (state=0,action)=>{
switch(action.type){
case "add":
return state+action.data;
case "min":
return state-action.data;
default:
return state;
}
}
export const usernameReducer = (state='柏拉文',action)=>{
switch(action.type){
case "change":
return action.data;
default:
return state;
}
}
4. index.js
入口文件全局订阅Store
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import store from './store'
const render = () => {
ReactDOM.render(
<App />,
document.getElementById('root')
);
}
render();
// 订阅 store
store.subscribe(render);
5. app.js
app组件使用Store
以及派发Store
import store from './store'
function App() {
const state = store.getState();
const handleChangeUsername = (value)=>{
// store 派发 修改 username Reducer
store.dispatch({type:'change',data:value});
}
const handleAddCount = (value)=>{
// store 派发 修改 count Reducer
store.dispatch({type:'add',data:value});
}
const handleMinCount = (value)=>{
// store 派发 修改 count Reducer
store.dispatch({type:'min',data:value});
}
return (
<div className="App">
<h3>{state.username}</h3>
<h3>{state.count}</h3>
<div>
<button onClick={()=>handleChangeUsername('柏拉文修改')}>修改 username</button>
<button onClick={()=>handleAddCount(1)}>增加 count</button>
<button onClick={()=>handleMinCount(1)}>减少 count</button>
</div>
</div>
);
}
export default App;
四、redux legacy 异步
Redux
只是个纯粹的状态管理器,默认只⽀持同步,实现异步任务 ⽐如延迟,⽹络请求,需要中间件的⽀持,⽐如我们试⽤最简单的redux-thunk
和redux-logger
。
1. 安装redux
、redux-thunk
、redux-logger
yarn add redux redux-thunk redux-logger -S
2. store --> index.js
用于创建Store
import { createStore, combineReducers,applyMiddleware } from "redux";
import { countReducer, usernameReducer } from "./reducer";
import Thunk from 'redux-thunk';
import Logger from 'redux-logger';
const reducer = combineReducers({
count:countReducer,
username:usernameReducer
});
const store = createStore(reducer,applyMiddleware(Logger,Thunk))
export default store;
3. store --> reducer.js
用于统一维护Reducer
export const countReducer = (state=0,action)=>{
switch(action.type){
case "add":
return state+action.data;
case "min":
return state-action.data;
default:
return state;
}
}
export const usernameReducer = (state='柏拉文',action)=>{
switch(action.type){
case "change":
return action.data;
default:
return state;
}
}
4. index.js
入口文件全局订阅Store
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import store from './store'
const render = () => {
ReactDOM.render(
<App />,
document.getElementById('root')
);
}
render();
// 订阅 store
store.subscribe(render);
5. app.js
app组件使用Store
以及派发Store
import store from './store'
function App() {
const state = store.getState();
console.log(state);
const handleChangeUsername = (value) => {
// store 派发 修改 username Reducer
store.dispatch({ type: 'change', data: value });
}
const handleChangeUsernameAsync = (value) => {
// store 派发 修改 username Reducer
store.dispatch((dispatch) => {
setTimeout(() => {
dispatch({ type: 'change', data: value });
}, 300);
});
}
const handleAddCount = (value) => {
// store 派发---同步增加 count Reducer
store.dispatch({ type: 'add', data: value });
}
const handleMinCount = (value) => {
// store 派发---同步减少 count Reducer
store.dispatch({ type: 'min', data: value });
}
const handleAddCountAsync = (value) => {
// store 派发---异步增加 count Red ucer
store.dispatch((dispatch) => {
setTimeout(() => {
dispatch({ type: 'add', data: value });
}, 300);
});
}
const handleMinCountAsync = (value) => {
// store 派发---异步减少 count Reducer
store.dispatch((dispatch) => {
setTimeout(() => {
dispatch({ type: 'min', data: value });
}, 300);
});
}
return (
<div className="App">
<h3>{state.username}</h3>
<h3>{state.count}</h3>
<div>
<button onClick={() => handleChangeUsername('柏拉文修改')}>同步修改 username</button>
<button onClick={() => handleChangeUsernameAsync('柏拉文修改')}>异步修改 username</button>
<button onClick={() => handleAddCount(1)}>同步增加 count</button>
<button onClick={() => handleMinCount(1)}>同步减少 count</button>
<button onClick={() => handleAddCountAsync(1)}>异步增加 count</button>
<button onClick={() => handleMinCountAsync(1)}>异步减少 count</button>
</div>
</div>
);
}
export default App;
五、redux react-redux legacy 同异步
5.1 认识
由于 Redux
通过在入口文件中进行订阅 store.subscribe(render)
之后, 在需要状态的组件中, 引入 store
文件即可访问、更新状态。那这样的话无法做到精确更新, 比如 A
组件需要状态 a
,B
组件需要状态 b
,那么改变 a
,只希望 A
组件更新,不希望 B
组件更新。所以, React-Redux
应运而生。
React-Redux
是连接 React
应用和 Redux
状态管理的桥梁, React-redux
主要专 注两件事,一是如何向 React
应用中注入 redux
中的 Store
,二是如何根据 Store
的改变,把消息派发给应用中需要状态的每一个组件。
-
向
React
注入redux
中的Store
:Redux
提供了一个Provider
组件, 可以全局注入redux
中的store
,所以使用者需要把Provider
注册到根部组件中。Provider
作用就是保存redux
中的store
,分配给所有需要state
的子孙组件。 -
订阅
Store
中的state
变化, 派发给应用中需要状态的每一个组件:Redux
提供了一个高阶组件connect
, 被connect
包装后组件将获得如下功能:-
能够从
props
中获取改变state
的方法Store.dispatch
-
如果
connect
有第一个参数,那么会将redux state
中的数据,映射到当前组件的props
中,子组件可以使用消费 -
当需要的
state
,有变化的时候,会通知当前组件更新,重新渲染视图
-
React-Recut
通过 Provider
组件解决了 Redux
状态共享的问题, 通过 connect
高阶组件订阅状态, 并通过传递第一个参数 mapStateToProps
来订阅具体依赖状态, 只有订阅具体的依赖状态发生变化, 才会触发业务组件更新视图。当这个参数没有的时候,当前组件不会订阅 store
的改变。