1.创建文件目录
*createStore------创建store实例
*reducer------------对当前state的拷贝修改
*actionTypes------把所有的action名称写在这里
*actionCreator----创建action对象的方法封装
2.获取state和改变state
获取:store.getState()
改变:store.subscribe(this.handleStoreChange);
handleStateChange:function(){this.setState(store.getState())}
3.actions对象创建
export const changeInput = (value) => ({
type: CHANGE_INPUT_VALUE,
value: value
})
4.store.dispatch(action)——执行action
5.组件分类
5.1UI组件
专门用来渲染dom的,一般只有一个render函数,少数的业务处理
5.2容器组件
专门用来处理业务逻辑,直接把UI组件导入
5.3无状态组件
只有render函数的组件,直接返回一段jsx代码;
一般来说只有一个render函数的组件都可以简写为返回一段代码的普通函数,这样就不用执行组件中其他的生命周期了
6.redux-thunk中间件
6.1作用
其实就是支持函数式的action,用来异步获取数据
6.2 store.dispatch(action)
这里的action里面的回调函数中有一个dispatch对象可以直接使用
6.3 两个中间件产生的冲突
redux-thunk、redux-devtools这两个中间件需要配置之后才能同时使用:
import {createStore, applyMiddleware, compose} from 'redux'
import reducer from './reducer'
import thunk from '../../node_modules/redux-thunk'
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(
applyMiddleware(thunk)
);
const store = createStore(reducer, enhancer);
export default store;
7异步获取数据第二把剑——redux-saga
7.1使用中间件
import {createStore, applyMiddleware, compose} from 'redux'
import reducer from './reducer'
import createSagaMiddleware from '../../node_modules/redux-saga'
import mySaga from './sagas'
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(mySaga)
export default store;
7.2创建一个空的action,在初始化时执行
componentDidMount() {
const action = getInitList()
store.dispatch(action)
}
saga.js在触发这个action后执行fetchUser
function* mySaga() {
yield takeEvery(GET_INIT_LIST, fetchUser);
}
然后在fetchUser中处理数据,相当于回调函数
function* fetchUser() {
try {
const res = yield axios.get('/api/todolist')
const action = initTodoList(res.data)
yield put(action)
} catch (e) {
alert('请求失败');
}
}
8.react-redux
8.1provider组件
provider组件能够向子组件共享store,使得它们都能够拿到store
import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList';
import {Provider} from 'react-redux'
import store from './store'
const App = (
<Provider store={store}>
<TodoList/>
</Provider>
)
ReactDOM.render(App, document.getElementById('root'));
8.2connect方法
export default connect(mapStateToProps, mapDispatchToProps)(TodoList)
mapStateToProps:第一个参数基本上都是属性,把state映射到props上面
const mapStateToProps = (state) => {
return {
inputValue: state.inputValue,
list: state.list
}
}
mapDispatchToProps:第二个参数把方法映射到props上,这些方法都是在执行action
Todolist:前面一个函数的参数,把UI组件填进去相当于创建了一个容器组件
9 再复习一遍redux基本流程
index.js (应用redux中间件以及reducer)
export default const store = createStore(reducer)
reducer.js(判断action执行相应方法)
const defaultState = {
inputValue: 'hello',
list: []
}
export default (state = defaultState, action) => {
if (action.type === 'change_input_value') {
const newState = JSON.parse(JSON.stringify(state))
newState.inputValue = action.value
return newState
}
return state
}
actionTypes.js:用变量封装action的名称
actionCreator.js:创建action对象