第一部分:redux
实战说明:
①创建store
import {createStore} from 'redux'
const store = createStore();
export default store;
②创建reducer
const defaultState = {
name:'lj',
value:18
}
export default (state=defaultState , action)=>{
if(action.type=='changeInput'){
let newState = JSON.parse(JSON.stringify(state));
newState.name =action.value;
return newState;
}
return state
}
③将reducer给store【整合第一步和第二部的代码】
import reducer from './reducer.js'
import {createStore} from 'redux'
const store = createStore(reducer);
export default store;
④获得store中的数据
import store from './store.js'
store.getState();//这里就是获得的store的数据
⑤改变store中的数据
const action ={
type:'changeInput',
value:'ceshi001'
}
store.dispatch(action)
⑥监听store的数据改变
class XXX extends Component{
constructor(props){
super(props);
store.subscribe(this.changeData)
}
}
第二部分:react-redux
综述:provider和connect
①使用提供器(provider),内部的其他组件都可以获得store,不需要每一个组件都引入store
import store from './store'
import {Provider} from 'react-redux';
const App =(
<Provider store={store}>
<TodoList></TodoList>
</Provider>
)
ReactDOM.render(App ,document.getElementById('root'));
②使用连接器(connect)
//将state映射为props,此时Todolist组件中可以使用this.props.inputValue获得数据;无需像之前一样,通过store获得其中的数据
const stateToProps=(state)=>{
return {
inputValue:state.inputValue
}
}
//将dispatch映射为props,此时可以使用this.props.changeValue()改变数据
const dispatchToProps=(dispatch)=>{
return{
changeValue(value){
let action={
type:'changeSign',
value:'value'
}
dispatch(action);
}
}
}
export default connect(stateToProps,dispatchToProps)(TodoList)
不用连接器的时候,是这样获得store的数据的
TodoList组件中需要import store,
然后通过 store.getState()获得store中的state;
使用连接器后,直接在props中就可以获得store中的数据
第三部分:redux中的异步-redux-thunk
用过react的人对redux一般多少都有一定了解,毕竟是作为react社区最热门的状态管理框架,相信不少人也是用过。redux并不能开箱即用,在异步上还需要依赖社区的第三方库。如redux-saga和redux-thunk
redux-thunk
出自redux的作者Dan,相信这个不少人都使用,相对于其他方案,使用起来比较简单。对于不太复杂的场景使用起来还是很方便的。使用起来就像下面的样子:
用法
首先,我们还是来看一下这个库的用法。redux-thunk是作为redux的 middleware 存在的,用法和普通 middleware 的用法是一样的,注册 middleware 的代码如下:
import thunkMiddleware from 'redux-thunk'
const store = createStore(reducer, applyMiddleware(thunkMiddleware))
注册后可以这样使用:
// 用于发起登录请求,并处理请求结果
// 接受参数用户名,并返回一个函数(参数为dispatch)
const login = (userName) => (dispatch) => {
dispatch({ type: 'loginStart' })
request.post('/api/login', { data: userName }, () => {
dispatch({ type: 'loginSuccess', payload: userName })
})
}
store.dispatch(login('Lucy'))
可以看到,redux-thunk主要的功能就是可以让我们dispatch一个函数,而不只是普通的 Object。后面我们会看到,这一点改变可以给我们巨大的灵活性。
第四部分:redux中的异步-redux-saga
第一步骤:安装中间件
npm install --save redux-saga //yarn add redux-saga也是可以的
第二步骤:创建store
import {createStore, applyMiddleware, compose} from 'redux';
// import thunk from 'redux-thunk';
import createSagaMiddleware from 'redux-saga';
import todoSagas from './sagas'
import reducer from './reducer';
const sagaMiddleware = createSagaMiddleware()
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware));
const store = createStore(
reducer,
enhancer
);
sagaMiddleware.run(todoSagas)
export default store;
此时此刻我们发现store.js中多了一句话:sagaMiddleware.run(todoSagas),todoSagas是从sagas中引过来的,具体思路是什么呢?
就是我们需要建立一个sagas.js文件,可以专门来存放异步请求,然后在store.js中需要调用saga中间件的run的方法去运行起来
第三步骤:在统一管理action的地方定义新的action变量
actionCreator.js
//getInitList函数返回一个对象,对象中有一个type类型
export const getInitList = () => ({
type : GET_INIT_LIST
})
第四步骤:在需要请求的地方建立action,同时通过dispatch传递给store
demo.js
componentDidMount(){
const action = getInitList()
console.log(action)
store.dispatch(action)
}
第五步骤:此时此刻,sagas.js开始起作用了,相当于除了reducer.js能够监听到action,而sagas.js同样也能监听到状态
import { takeEvery,put } from 'redux-saga/effects'
import { GET_INIT_LIST } from './actionTypes'
import {initListAction} from './actionCreators'
import axios from 'axios'
function* getInitList(){
try{
const res = yield axios.get("https://www.easy-mock.com/mock/5c4173448ff5e33c8a22766e/example/listdata")
const action = initListAction(res.data.result)
yield put(action)
}catch(e){
console.log('网络请求失败')
}
}
// generator 函数
function* mySaga() {
yield takeEvery(GET_INIT_LIST, getInitList);
}
export default mySaga;
其中takeEvery是redux-saga的方法,目的是监听到action(对于dispatch(actin)做出响应),而put的作用相当于dispatch的作用,将action传给store