22.标准的redux工作模型

2020-06-01  本文已影响0人  __疯子__

初始化项目目录

- src
  - actions
  - components
  - reducers
  - App.js
  - index.js
  - store.js

接口地址:http://jsonplaceholder.typicode.com/posts

1.在App.js中引入BlogList组件

import React,{Componet} from 'react';
import {BlogList} from './componets';
class App extends Componet{
  render(){
    return (
      <div><BlogList/></div>
    )
  }
}
export default App;

2.新建文件src/components/index.js

export {default as BlogList} from './BlogList/BlogList'

3.新建文件src/components/BlogList/BlogList.js

import React, {Component} from 'react';
import BlogItem  from './BlogItem';

class BlogList extends Component {
    //这里还需要对传入的数据做检测 prop-types

    render() {
        return (
            <ul>
                <BlogItem/>
            </ul>
        );
    }
}

export default BlogList;

4.新建文件src/components/BlogList/BlogItem.js

import React from 'react'
export default function BlogItem(){
    return(
        <li>BlogItem</li>
    )
}

5.新建文件src/reducers/index.js

import { combineReducers } from 'redux'
import Blog from './blog'

export default combineReducers({
  blog
})

6.新建文件src/reducers/blog.js

//初始化数据
const initState=[
    {
        "userId": 1,
        "id": 1,
        "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
        "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
    },
    {
        "userId": 1,
        "id": 2,
        "title": "qui est esse",
        "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
    }
];
export default (state=initState, action) => {
    switch (action.type) {
        
        default:
            return state;
    }
}

7.创建store.js

import {createStore,applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
export default createStore(
    rootReducer,
    applyMiddleware(thunk),//使用中间件
);

8.引用Provider src/index.js

import React from 'react'
import {render} from 'react-dom'
import App from './App'
//Provider是react-redux提供的组件
import {Provider} from 'react-redux'
import store from './store'
render(
    <Provider store={store}>
        <App/>
    </Provider>,
    document.getElementById("root")
);

9.使用store(connect) (src/components/BlogList/BlogList.js)

import {connect} from 'rect-redux';

10.修改导出配置src/components/BlogList/BlogList.js

const mapState=state=>({
  blogList:state.blog
})
export default connect(mapState)(BlogList)

11.添加加载状态src/reducers/blog.js

const initState = {
    list: [
        {
            "userId": 1,
            "id": 1,
            "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
            "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
        },
        {
            "userId": 1,
            "id": 2,
            "title": "qui est esse",
            "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
        }
    ],
    isLoading:false,
};

12.修改结构时参数src/components/BlogList/BlogList.js

const mapState=state=>({
    list:state.Blog.list,
    isLoading:state.Blog.isLoading,
});

13.遍历数据src/components/BlogList/BlogList.js

    render() {
        console.log(this.props.list)
        return (
            <ul>
                {
                    this.props.list.map(blog=>{
                        return (
                            <BlogItem key={blog.id} {...blog}/>
                        )
                    })
                }
            </ul>
        );
    }

14.修改子组件src/components/BlogList/BlogItem.js

import React from 'react'

export default function BlogItem(props){
    return(
        <li>
            <h3>{props.title}</h3>
            <p>{props.body}</p>

        </li>
    )
}

15.加上loading状态src/components/BlogList/BlogList.js

    render() {
        console.log(this.props.list)
        const {
            list,
            isLoading
        } = this.props;
        return isLoading ? <div>loading...</div> :
            <ul>
                {
                    list.map(blog => {
                        return (
                            <BlogItem key={blog.id} {...blog}/>
                        )
                    })
                }
            </ul>
    }

16.使用axios进行数据请求

cnpm i -D axios

创建文件src/services/index.js

import axios from 'axios'

const ajax=axios.create({
    baseURL:'http://jsonplaceholder.typicode.com',
})
export const getPosts=()=>ajax.get('/posts');

17.创建文件src/actions/actionTypes.js

export default{
  START_FETCH_BLOG_LIST:'START_FETCH_BLOG_LIST',//正在请求      
  FETCH_BLOG_LIST_SUCCESS:'FETCH_BLOG_LIST_SUCCESS',//请求完成
  FETCH_BLOG_LIST_FAILED:'FETCH_BLOG_LIST_FAILED',//请求失败  
}

18.新建文件src/actions/blog.js

import actionTypes from './actionType'
import {getPosts} from "../services";

/**
* 开始请求
* @return {{type: string}}
*/
const startFetchBlogList=()=>{
   return {
       type:actionTypes.START_FETCH_BLOG_LIST
   }
};

const fetchBlogListSuccess=(payload)=>{
   return {
       type:actionTypes.FETCH_BLOG_LIST_SUCCESS,
       payload
   }
};
const fetchBlogListFailed=()=>{
   return {
       type:actionTypes.FETCH_BLOG_LIST_FAILED
   }
};
export const fetchBlogList=()=>dispatch=>{
   dispatch(startFetchBlogList());
   getPosts().then(res=>{
       if(res.status===200){
           dispatch(fetchBlogListSuccess({list:res.data}))    
       }else{
           dispatch(fetchBlogListFailed())    
       }
   }).catch(error=>{
       console.log(error);
       dispatch(fetchBlogListFailed())
   })
};

19.引入action (src/components/BlogList/BlogList.js)

import {fetchBlogList} from "../../actions/blog";


componentDidMount() {
   this.props.fetchBlogList()
}

20.src/reducers/blog.js进行数据处理,及返回状态处理

import actionTypes from '../actions/actionType';

//初始化数据
const initState = {
    list: [
        {
            "userId": 1,
            "id": 1,
            "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
            "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
        },
        {
            "userId": 1,
            "id": 2,
            "title": "qui est esse",
            "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
        }
    ],
    isLoading:false,
};
export default (state = initState, action) => {
    switch (action.type) {
        case actionTypes.START_FETCH_BLOG_LIST:
            return{
                ...state,
                isLoading:true,
            };
        case actionTypes.FETCH_BLOG_LIST_SUCCESS:
            return {
                ...state,
                isLoading:false,
                list:action.payload.list
            };
        case actionTypes.FETCH_BLOG_LIST_FAILED:
            return {
                ...state,
                isLoading:false,
                list:[{title:"没有数据啦"}]
            };
        default:
            return state;
    }
}

从深往浅理解:

1. `src/components/BlogList/BlogList.js`中调用了this.props.fetchBlogList();这个函数是从state中读取的并且使用connect()进行了传递,所以可以获取到this.props.fetchBlogList()这个函数
2. 函数定义位置是在`src/actions/blog.js`中导出的fetchBlogList函数
在fetchBlogList函数中进行了数据请求`getPost`函数,并且使用dispatch进行保存当前请求状态
在这里有一点知识难点,需要在请求成功后传值到下一个执行函数中`dispatch(fetchBlogListSuccess({.......}))`
3.使用dispatch函数调用的方法会被`src/reducers/index.js`文件进行接收,并以`combineReducers`进行合并,也就是最终调用位置为`src/reducers/blog.js`文件的默认导出函数,默认导出的函数处理当前状态及数据反回给`react-redux`(在`src/components/BlogList/BlogList.js`文件中有引用,)
4.最终的数据解析位置是在`src/components/BlogList/BlogList.js`的mapState中进行解析的数据
上一篇 下一篇

猜你喜欢

热点阅读