美文网首页
2019-03-18 redux-thunk 解读

2019-03-18 redux-thunk 解读

作者: KingAmo | 来源:发表于2019-03-18 10:44 被阅读0次

    thunk的概念

    A thunk is a function that wraps an expression to delay its evaluation.

    • thunk 是一种函数,他包裹着一个表达式,让这个表达式延迟他的计算。
    • call-by-value call-by-reference call-by-name 惰性求值
    // 立即计算 1+2 这个表达式的值
    // x === 3
    let x = 1 + 2;
    
    // 计算 1 + 2 这个表达式的过程被延迟了
    // 可以在随后的任意时刻来调用foo 来计算 1+2 的值
    // foo 就是一个 thunk
    let foo = () => 1 + 2;
    
    const hypot = (x, y) => Math.sqrt(x * x + y * y);
    
    // 'thunk' 是一个没有参数的函数, 当他被调用的时候,执行一些昂贵的操作 或者产生一些 `side-effect`
    // 这里不用thunk的话,就已经计算得到5了
    const thunk = () => hypot(3, 4);
    
    // 然后这个 thunk 就能被当成参数被传递
    doSomethingWithThunk(thunk);
    
    // 或者被调用,这时候才被计算,得到5
    thunk(); // === 5
    

    PS:thunk这个术语(term) 来源于think 这个单词的一种幽默的过去式

    为什么要用 redux thunk

    Redux深受函数式编程的影响,创造性的不支持副作用的执行。
    尤其是 reducer, 必须 是符合 (state, action) => newState 的纯函数。
    然而, Redux Thunk 能拦截分发的 action 并添加额外的复杂行为,还可以添加副作用。
    这样就能用更为复杂或者异步的逻辑书写 action 创建函数
    类似作用的中间件还有Redux SagaRedux Loop

    Github 关于redux-thunk的介绍

    redux-thunk

    With a plain basic Redux store, you can only do simple synchronous updates by dispatching an action. Middleware extend the store's abilities, and let you write async logic that interacts with the store.

    • store存储着应用的所有状,如果你仅仅使用redux的基本的store,你只能通过dispatch action 来做一些同步的数据更新(和store交互)。但是通过 中间件 能扩展 store 的能力,让你能写一些 异步 的逻辑来和store进行交互。

    Thunks are the recommended middleware for basic Redux side effects logic, including complex synchronous logic that needs access to the store, and simple async logic like AJAX requests.

    • Thunks 是使redux 能够使用 副作用 相关的逻辑的一种推荐的中间件。比如很复杂的需要和store交互的 同步 逻辑、或者简单的 AJAX 请求的 异步逻辑。

    Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch and getState as parameters.

    • redux thunk 中间件允许你写的 action creators 返回一个 function ,而不是一个 actionthunk 能延迟 dispatch 一个 action,或者说只有特定条件发生的时候才 dispatch 一个 action。(很明显很适合AJAX请求,当得到数据返回时,再发出action)

    总结

    不使用 redux-thunk 时,如果在异步请求中使用redux,要发出三个action

    function loadData(dispatch, userId) { // needs to dispatch, so it is first argument
      dispatch({type: 'START'}); // 异步开始时发出一个
      return fetch(`http://data.com/${userId}`)
        .then(response => response.json())
        .then(json => dispatch({type: 'SUCCESS', payload: json}))
        .catch(err => dispatch({type:'FAILE',payload: err}))
      };
    };
    
    componentDidMount() {
      loadData(this.props.dispatch, this.props.userId); // don't forget to pass dispatch
    }
    

    如上, 发起这个异步请求是调用loadData()函数,在loadData函数里,会在合适的时机发出合适的action


    而使用 redux-thunk 时 ,发起异步请求是dispatch一个函数 —— 调用 loadData()返回的一个函数,然后再发出具体的action对象。而普通的 Action Creator 默认返回一个对象。

    也就是说,使用redux-thunk中间件,改造了 store.dispatch,使得后者可以接受函数作为参数,而这个函数的功能就是在合适的时机发出三个action

    这么做的好处是,不必在componentDidMount里写一堆网络请求相关的代码了

    // action creator
    loadData = userId => (dispatch, getState) => {
      fetch(`http://data.com/${userId}`) // Redux Thunk handles these
        .then(res => res.json())
        .then(
          data => dispatch({ type: 'LOAD_DATA_SUCCESS', data })
        )
        .catch(
          err => dispatch({ type: 'LOAD_DATA_FAILURE', err })
        )
    }
    
    componentDidMount() {
      this.props.dispatch(loadData(this.props.userId)); // dispatch like you usually do
    }
    

    总结来说,redux-thunk 的作用就是让reduxstore.dispatch 能接受函数作为参数,然后你就可以发挥你的想象来写这个函数的功能,完成一些你需要的功能。

    参考链接

    相关文章

      网友评论

          本文标题:2019-03-18 redux-thunk 解读

          本文链接:https://www.haomeiwen.com/subject/dnammqtx.html