最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 【React学习笔记】Redux,React-redux,Redux-thunk的使用

    正文概述 掘金(明月何时赵我还)   2021-01-26   426

    Redux

    Redux的使用

    import {createStore} from 'redux';
    
    const store = createStore((state={count:1,name:'xiaoming'},action)=>{
        switch(action.type){
            case 'ADD':
                return {
                    ...state,
                    count:state.count+1
                }
            case 'MINS':
                return {
                    ...state,
                    count:state.count-1
                }
            default:
                return {
                    ...state,
                    count:state.count
                }
        }
    })
    
    export default store;
    

    createStore中传入reducer,reducer是一个函数,有两个参数state和action,通过判断action的判断来对state执行不同的操作;

    Redux api

    createStore(reducer, [preloadedState], enhancer); 
      - reducer (Function): 接收两个参数,分别是当前的 state 树和要处理的 action,返回新的 state 树。
      - [preloadedState] (any): 初始时的 state。 在同构应用中,你可以决定是否把服务端传来的 state 后传给它,或者从之前保存的用户会话中恢复一个传给它。如果你使用 combineReducers 创建 reducer,它必须是一个普通对象,与传入的 keys 保持同样的结构。否则,你可以自由传入任何 reducer 可理解的内容。
      - enhancer (Function): Store enhancer 是一个组合 store creator 的高阶函数,返回一个新的强化过的 store creator。这与 middleware 相似,它也允许你通过复合函数改变 store 接口。
      - 返回值 (Store): 保存了应用所有 state 的对象。改变 state 的惟一方法是 dispatch action。你也可以 subscribe 监听 state 的变化,然后更新 UI。
    reducer 
      - reducer(state,action)
      
    Store 
      - getState()
      - dispatch(action):dispatch传入action对象,触发reducer;
      - subscribe(listener):subscribe用来监控state的变化,返回的参数用来取消监控;
      - replaceReducer(nextReducer):replaceReducer替换reducer;
    
    combineReducers(reducers)
      将 reducer 函数拆分成多个单独的函数,拆分后的每个函数负责独立管理 state 的一部分
    
    applyMiddleware(...middlewares) 中间件
    

    Redux三大原则

    1. 单一数据源:整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中

    2. state是只读的:唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象

    3. 使用纯函数来执行修改

      高阶函数和纯函数

    reducer的拆分与合并

    使用combineReducers合并reducer

    import { createStore, combineReducers} from "redux";
    /*
      reducer 的拆分与合并:
      action.type 在项目中时唯一的
    */
    
    //reducer的拆分
    const count = (count=1,action)=>{
      switch (action.type) {
        case "COUNT_ADD":
          return count + 1;
        case "COUNT_MINS":
          return count - 1;
        default:
          return count;
      }
    }
    const list = (list={
      type: "all",
      data: [],
      nub: 1
    },action)=>{
      switch (action.type) {
        case "LIST_ADD":
          return {
            ...list,
            nub: list.nub + 1
          }
        case "LIST_MINS":
          return {
            ...list,
            nub: list.nub - 1
          };
        default:
          return list;
      }
    }
    
    // reducer 的合并
    // const reducer = (state = {
    //   count: 1,
    //   list: {}
    // }, action) => {
    //   return {
    //     count:count(state.count,action),
    //     list: list(state.list,action)
    //   }
    // }
    
    // reducer 的合并
    const reducer = combineReducers({
      count,
      list
    });
    
    const store = createStore(reducer);
    
    export default store;
    

    React-redux

    状态绑定

    将仓库(store)通过Provider组件传给App

    import ReactDOM from 'react-dom';
    import App from './App';
    import { Provider } from 'react-redux';
    import store from './store';
    
    ReactDOM.render(
        <Provider store={store}>
            <App></App>
        </Provider>,
        document.querySelector("#root")
    );
    

    接收参数

    • connect
    const withConnect = connect((state) => {
        const {count} = state;
        return {count};//返回值是state中要传递给组件的数据,必须是一个对象!
    })
    
    //App传下来的props通过withConnect会自动组合到state中传给App组件
    export default withConnect(App);
    
    • hooks
    1. useDispatch获取dispatch

    2. useStore获取store

    3. useSelector获取state

    import { useDispatch, useSelector, useStore } from "react-redux"
    
    function App(props) {
        const dispatch = useDispatch();
        const count = useSelector(state=>state.count);
        const store = useStore();
        console.log(store.getState());
        console.log(props);
        return <div>
            <p>{count}</p>
            <button onClick={() => {
                dispatch({ type: 'ADD' })
            }}>+</button>
            <button onClick={() => {
                dispatch({
                    type: 'MINS'
                })
            }}>-</button>
        </div>
    }
    
    export default App;
    

    redux-thunk

    ps:不是react-thunk !!!

    使用

    使用 thunk 中间件后,action可以支持两种形式: "函数" 和 "对象"

    1. 参数是对象,直接调用 reducer 修改我们的 state
    2. ,参数是函数调用该函数,并且把 dispatch 和 getState 传递我们的函数,可以在函数中,进行异步操作
    import { createStore, applyMiddleware} from "redux";
    import thunk from "redux-thunk";
    const reducer = <你的reducer>
    const store = createStore(reducer,applyMiddleware(thunk));
    

    异步获取数据问题

    举例:根据不同的type获取cnode( cnodejs.org/api )的list数据

    store.js

    import { createStore, combineReducers, applyMiddleware} from "redux";
    import thunk from "redux-thunk";
    
    const list = (list={
      type: "all",
      data: [],
      loading: true
    },action)=>{
      switch (action.type) {
        case "LIST_LOADING":
          return {
            ...list,
            data: [],
            loading: true
          }
        case "LIST_LOAD":
          return {
            ...list,
            data: action.data,
            loading: false
          }
        case "LIST_TYPECHANGE":
          return {
            ...list,
            type: action.dataType,
          }
        default:
          return list;
      }
    }
    
    const reducer = combineReducers({
      list
    });
    const store = createStore(reducer,applyMiddleware(thunk));
    
    export default store;
    

    app.js

    import { useEffect } from "react";
    import { useSelector,useDispatch } from "react-redux";
    import { getListData } from "./actions";
    // ask share job good
    function App() {
      const list = useSelector(state => state.list);
      const {type,data,loading} = list;
      const dispatch = useDispatch();
      useEffect(()=>{
        dispatch(getListData);
      },[type]);
      return <div>
        <button onClick={()=>{
          dispatch({
            type: "LIST_TYPECHANGE",
            dataType: "all"
          })
        }}>all</button>
        <button onClick={()=>{
          dispatch({
            type: "LIST_TYPECHANGE",
            dataType: "ask"
          })
        }}>ask</button>
        <button onClick={()=>{
          dispatch({
            type: "LIST_TYPECHANGE",
            dataType: "share"
          })
        }}>share</button>
        {loading?<div>数据更新中</div>:<ul>{
          data.map(item=><li key={item.id}>{item.title}</li>)
        }</ul>}
        
      </div>
    }
    
    export default App;
    
    import axios from "axios";
    function getListData(dispatch, getState) {
      dispatch({
        type: "LIST_LOADING"
      });
      axios.get(`https://cnodejs.org/api/v1/topics?page=1&tab=${getState().list.type}&limit=10`).then(res => {
        dispatch({
          type: "LIST_LOAD",
          data:res.data.data
        })
      })
    }
    export { getListData };
    

    起源地下载网 » 【React学习笔记】Redux,React-redux,Redux-thunk的使用

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元