redux 原理图

react-redux 改的地方
自动刷新
原本的更改需要在 index.js 下 自己手动更新,react-redux 可以自动刷新
store.subscribe(()=>{ReactDOM.render(<App/>,document.getElementById('root'))})
将所有组件分为两大类
- **UI组件**- 只负责 UI 的呈现,不带有任何业务逻辑- 通过props接收数据(一般数据和函数)- 不使用任何 Redux 的 API- 一般保存在components文件夹下- **容器组件**- 负责管理数据和业务逻辑,不负责UI的呈现- 使用 Redux 的 API- 一般保存在containers文件夹下
文件夹结构的优化
优化后 两大类组件UI/容器 就都放在 containers 文件夹下了
src下:
react-redux API
Provider
让所有组件都能得到 state 数据
import React from 'react'import ReactDOM from 'react-dom'import App from './App'import store from './redux/store'import {Provider} from 'react-redux'ReactDOM.render(<Provider store={store}><App/></Provider>,document.getElementById('root'))
connect 用于包装 UI 组件生成容器组件 ,非常重要!
import { connect } from 'react-redux'connect(mapStateToprops,mapDispatchToProps)(UIcomponent)
mapStateToprops:将外部的数据(即state对象)转换为UI组件的标签属性
mapDispatchToProps:将分发action的函数转换为UI组件的标签属性
redux 开发者工具
chrome 商店
还需要下载工具依赖包npm install --save-dev redux-devtools-extension
在 store.js 中调用
import { createStore, applyMiddleware } from "redux";import thunk from "redux-thunk";import {composeWithDevTools} from 'redux-devtools-extension'//**import allReducers from './reducers'export default createStore(allReducers, composeWithDevTools(applyMiddleware(thunk)));//***
简述写出一个 使用到 react-redux 的组件的流程
正常写出一个 组件 作为 UI组件,没什么要注意的。这里举例用的组件名称为 Count
使用 connect 包装UI组件,并且暴露出去
src/containers/Count/index.jsx
import { connect } from "react-redux";import {increment,decrement,incrementAsync,} from "../../redux/actions/count";//用于 connect 的第二个参数export default connect(state => ({count: state.counts,personNumber: state.persons.length,}),// dispatch => ({// increment: data => dispatch(createIncrementAction(data)),// decrement: data => dispatch(createDecrementAction(data)),// incrementAsync: (data, time) =>// dispatch(createIncrementAsyncAction(data, time)),// }),{increment,decrement,incrementAsync,})(Count);
mapDispatchToProps 可以传方法也可以直接传一个对象,省略大量的 dispatch ,react-redux 会自动帮你调用 dispatch,触发对象传值的简写方式后简单明了。
connect 这里面传的东西都会作为 props 到 UI组件中,数据、方法 就都可以使用了。
src/redux/actions/count.js
然后是** /redux/actions/count**里面要写的东西,其实一般应该是 先写了这里然后再到上面的 connect 中使用。
每个 create actions 是函数,然后都是分别暴露以供 Count 组件使用,如果是异步的就是函数中返回函数。
import { INCREMENT,DECREMENT } from "../constant";export const increment = data => ({type: INCREMENT,data,})export const decrement = data => ({type: DECREMENT,data,})export const incrementAsync = (data,time) => {return (dispatch)=>{setTimeout(() => {dispatch(increment(data))},time)}}
注意这里的constant文件 ,里面就是存放工程所需要的所有 action 的 type 。将 type 的字符串全部存起来,防止 coder 打错字造成低级的bug。
src/redux/count.js
后厨啦,就是接受到原料 preState 和方法 action(里面有type—干什么,data—搞多少)啦,整完再传出去 newState 啦。
import { INCREMENT,DECREMENT } from "../constant";const initState = 0export default function countReducer(pre=initState, action) {const { type, data } = action;switch (type) {case INCREMENT:return pre + data;case DECREMENT:return pre - data;default:return pre}}
react-redux 在初始化时会自动调用 reducer 这时传入的第一个参数就是 undefined ,设置的初始化数据 initState 就派上用场了。
src/redux/reducers/index.js
一般后厨不止一个,那么要整合到一块成为一组传递给 store。语法也很简单,就是要用到 redux 中combineReducers这个API了
import { combineReducers } from "redux";import counts from "./count";import persons from "./person";export default combineReducers({ counts, persons });
src/redux/store.js
使用 createStore 这个函数来创造一个 store,并且暴露出去。
import { createStore, applyMiddleware } from "redux";import thunk from "redux-thunk";import {composeWithDevTools} from 'redux-devtools-extension'import allReducers from './reducers'export default createStore(allReducers, composeWithDevTools(applyMiddleware(thunk)));
这里的中间件"redux-thunk",是有些异步操作所需要的,别问,问就是 redux API 就是如此。import allReducers from './reducers'这句话就是从 reduces 文件下调来一个 整合的 所有 reducers,即allReducers,第二个参数composeWithDevTools就是上面提到的 因为要使用 开发者工具的依赖包。
完成
至此就完成了 一个 Count 组件,可以从 redux 获得数据来操作了。
