Redux学习心得,附github项目链接
Redux特点
- 统一的状态管理,一个应用中只有一个仓库(store)
- 仓库中管理了一个状态树(statetree)
- 仓库不能直接修改,修改只能通过派发器(dispatch)派发一个动作(action)
- 更新state的逻辑封装到reducer中,reducer是纯函数
Redux流程图
Rdeux中重要对象说明
store
是一个数据仓库,一个应用中store是唯一的,它里面封装了state状态,当用户想访问state的时候,只能通过store.getState来取得state对象。
action
action描述了一个更新state的动作,它是一个对象,其中type属性是必须有的,reducer会根据type来指定某动作和要修改的值。
{
type: FETCH_POSTS,
payload: posts // 数据源
}
dispatch
dispatch是一个方法,它用于派发一个action,这是唯一的能够修改state的方法。
fetch("https://jsonplaceholder.typicode.com/posts")
.then(
posts => dispatch({
type: FETCH_POSTS,
payload: posts
})
)
reducer
reducer是更新state的核心,它里面已经封装好了更新state的逻辑,接受两个参数,state和action,将新值更新到旧的state对象上返回。
// 根据action的type,返回不同数据
switch (action.type) {
case FETCH_POSTS:
return {
...state,
items: action.payload
};
default:
return state;
}
React中使用Redux
项目目录结构
入口文件index.js
import { Provider } from 'react-redux';
import { store } from './redux/store';
// Provider包裹之后,所有的组件都可以拿到store库中数据
<Provider store={store}>
// 项目中常用Provider包裹最底层父组件,以保证所有组件都能共享数据
<Index />
</Provider>
数据仓库store.js
- 引入所需文件和插件
import {applyMiddleware, createStore} from "redux";
import rootReducer from './reducers/index.js';
import thunk from 'redux-thunk'; // thunk作用是异步的分发action
const middleware = [thunk]; // 中间件
const initialState = {};
- 通过createStore方法创建库,接受三个参数(reducer,state,中间件)
// applyMiddleware将所有中间件组成一个数组并依次执行
export const store = createStore(
rootReducer,
initialState,
applyMiddleware(...middleware),
);
actions/postAction.js
// 分发操作
export const fetchPosts = () => dispatch => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then(res => res.json())
.then(posts => dispatch({
type: 'FETCH_POSTS', // type是必须要有的
payload: posts // 有效数据
}));
};
reducers/postReducer.js
const initialState = {
items: [],
item: {}
};
// reducer接受两个参数,第一个是state,第二个是action
export default function (state = initialState, action) {
switch (action.type) {
case FETCH_POSTS:
return {
...state,
items: action.payload
};
default:
return state;
}
}
组件触发action
- 以components中的Posts组件来说明,引入所需数据和方法
import {connect} from 'react-redux';
import {fetchPosts} from "../redux/actions/postActions";
@connect(state => {
let {items, item} = state.posts;
return {
items,
item
}
},{fetchPosts})
- 通过this.props引入
componentDidMount () {
this.props.fetchPosts();
}
componentWillReceiveProps (nextProps) {
if(nextProps.item){
this.props.items.unshift(nextProps.item);
}
}
项目完整代码
https://github.com/GaoHeming111/create-react-app-
补充
引入第三方库antd时按需加载
yarn add babel-plugin-import --save
// 在package.json中添加
"babel": {
"presets": [
"react-app"
],
"plugins": [
[
"import",
{
"libraryName": "antd",
"style": "css"
}
]
]
}
connect装饰器写法
- 未用装饰器写法
// 将最新的state映射到当前组件,通过mapStateToProps订阅store
const mapStateToProps = state => ({
posts: state.posts.items,
});
// 将当前组件Posts和action进行链接
// connect接受两个参数,第二个参数里面可以包含多个方法
export default connect(mapStateToProps,{fetchPosts})(Posts)
- 使用装饰器写法
yarn add babel-plugin-transform-decorators-legacy
// 可省略如上步骤,在头部引入所需state和action,然后直接导出组件
@connect(state => {
let {
items,
item
} = state.posts;
return {
items,
item
}
},{fetchPosts}),
export default Posts;
欢迎联系
一些学习心得,有错请留言指正哈,也可加入公众号我们一起学习~