redux、react-redux状态管理应用

redux

仅仅是用来管理组件的状态,需要满足以下条件:

  1. 用户使用方式复杂
  2. 不同的用户、不同使用方式(普通用户和管理员);
  3. 多个用户之间的协作;
  4. 与服务器有大量的交互;
  5. View有多个数据源。

其他场景下,能不用redux就不用,否则增加项目的复杂度。

三大特征:

  1. 单一的数据源,整个应用的state都存储与store对象中;
  2. state只读,只有触发Action(用于描述发生的事件)才能改变state;
  3. 使用纯函数(函数的返回值只能依赖于它的参数,相同的输入,只能得到相同的结果)执行修改。

由三个部分构成:

1. Action,描述事件,是信息的载体

2. Reducer,定义事件,规定整个应用的状态如何改变,根据Action更新Store中的状态

3. Store,存储整个应用的状态


createStore(reducer,[preloadedState],[enhancer])

创建一个store来存放应用中所有的state,并且应用中只能有一个store。

参数reducers接受两个参数:当前的state和要执行的Action,返回新的state


Store

  1. getState(),获取state,
  2. dispatch(action),分发action,触发state变化的唯一途径
  3. subscribe(listener),用于注册回调,监听state变化
  4. replaceReducer(nextReducer),更新当前Store内的Reducer

常用getState()、dispatch(action)

combinReducers(reducers)

将多个reducer函数组合成一个reducer函数


applyMiddleware(…middlewares)

是包装了 store 的 dispatch 方法


bindActionCreates(actionCreators,dispatch)

把一个 value 为不同 action creator 的对象,转成拥有同名 key 的对象。


compose(…function)

组合组合多个函数

react-redux

<Provider store>:让组件层级中的connect()方法能够获取到Redux Store
一个容器的作用,实现store的上下文传递。

connect

从UI组件生成容器组件

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])

连接react组件和Redux,形成容器组件:

import {connect} from "react-redux";
const Count = connect()(List);

mapStateToProps和mapDispatchToProps,定义了UI组件的业务逻辑。mapStateToProps主要输入逻辑,即是将state转化为组件的props属性;mapDispatchToProps输出逻辑,将用户对UI组件操作映射为action。

如下例子:
app.js

import React from 'react';
import { Provider } from 'react-redux';
import './App.css';
import store from "./store"
import Posts from "./components/Posts";

function App() {
    return (
        <Provider store={store}>
            <Posts />
        </Provider>
    );
}

export default App;

正如上文所说:store是一个保存数据的地方(容器),一个应用中只能有一个store:
store.js

import {createStore,applyMiddleware, compose} from "redux";
import thunk from "redux-thunk";
import rootReducer from "./reducers/index";

const initialState ={};


const middleware =[thunk];

const store = createStore(rootReducer,initialState,compose(
    applyMiddleware(...middleware),
    window .__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()  //在浏览器中查看redux请求的数据
));

export default store

reducers文件下创建一个index.js,组合多个reducer函数

import {combineReducers} from "redux";
import postReducer from "./postReducer";

export default combineReducers({
    posts:postReducer
})

reducer函数:

//引入dispatch的type类型
import {FETCH_POST} from "../actions/types";

//reducer的作用就是返回一个新的状态
const initialState = {
    //存储自己想要的状态
    item:[]        //访问当前文件中的时候定义一个初始状态(数据)
}

/**
 * reducer是一个纯函数,接收旧的state和action,返回新的state
 * @param {*} state 
 * @param {*} action 
 */
export default function(state=initialState,action){
    switch(action.type){  
        case FETCH_POST:
            return {
                ...state,
                item:action.payload
            }
        default:
            return state
    }
}

actions文件下创建

types.js定义操作的类型:

export const FETCH_POST = "FETCH_POST";

action.js,描述操作事件,获取数据:

import { FETCH_POST } from "./types";

export const fetchPost = () => dispatch => {
    fetch("http://jsonplaceholder.typicode.com/users")
        .then(res => {
            return res.json()
        })
        .then(data => {
            console.log(data)
            //内容分发
            dispatch({
                type: FETCH_POST,
                //把请求的数据返回去
                payload: data
            })
        })
}

ui组件引用如下:

import React, { Component } from "react";
//给之前的状态规定一个数据类型,
import propTypes from 'prop-types';

//在posts中使用fetchpost方法,需要用reducer中提供的connect来连接

import { connect } from 'react-redux';
import { fetchPost } from "../actions/allAction"
class Posts extends Component {
    //数据从redux中拿取,则不需要使用constructor了
    componentDidMount() {
        this.props.fetchPost()
    }
    render() {
        console.log(this.props)
        const postItem = this.props.posts.map((item) => (
            <div key={item.id}>
                <h3>name:{item.name}</h3>
                <p>email:{item.email}</p>
            </div>
        ))
        return <div>{postItem}</div>
    }
}

/**
 * 把返回的状态转化为我们的属性props
 */
const mapStateToProps = state=>({
    /**
     * state中的posts,是在reducers中index.js定义的posts
     * item中posts的属性在postReducer.js定义的初始值
     */
    posts:state.posts.item
});

//规范方法和状态的使用类型
Posts.propTypes={
    fetchPost:propTypes.func.isRequired,
    posts:propTypes.array.isRequired
}

/**
 * connet接受两个参数(方法)
 * connet(mapStateToProps,{fetchPost})
 */
export default connect(mapStateToProps,{fetchPost})(Posts)

在这里插入图片描述
源码

发布了102 篇原创文章 · 获赞 26 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/xuelian3015/article/details/103469209