【问题标题】:How to trigger loading animation from a loading action in react/redux如何从 react/redux 中的加载动作触发加载动画
【发布时间】:2019-11-15 18:52:33
【问题描述】:

我正在开发我的第一个 react/redux 网络应用程序,该应用程序从外部 api 获取音乐会。我的动作创建者对此有几个动作,包括"LOADING_CONCERTS", "GET_CONCERTS", AND "SET_CONCERTS"。然后,我将这些音乐会呈现在音乐会列表组件中。是否可以在 redux 在加载操作时添加加载栏组件来渲染?一些代码:

我的异步 axios:

export const getConcerts = (artist) => {
      return (dispatch) => {
        dispatch({ type: 'LOADING_CONCERTS' });
        return axios.get(${api_url})
          .then(concerts => {
            dispatch({ type: 'GET_CONCERTS', concerts })
            dispatch({ type: 'SET_CONCERTS', concerts })
            dispatch(addReviewsToConcerts(concerts))
          })
          .catch( err=> {
            console.log(err.code)
            console.log(err.message)
            console.log(err.stack)
          }
          )
        }
    }

我的减速机:

const initialState = []

export default (state = initialState, action) => {
  switch (action.type) {
    case 'LOADING_CONCERTS':
      return state;
    case 'GET_CONCERTS':
      return action.concerts.data
    case 'ADD_REVIEWS_TO_CONCERTS':
      return action.concerts
    case 'SAVE_CONCERT':
      return action
    default:
      return state;
  }
}

音乐会容器:


import React from 'react';
import ConcertSearchFormWrapper from './ConcertSearchFormWrapper';
import ConcertsList from '../.././components/concerts/ConcertsList';
import { connect } from 'react-redux';

const Concerts = (props) => {
    return (
      <div className="concerts-container">
        <ConcertSearchFormWrapper />
        { (props.concerts.length > 0 && props.concerts !== '\n{warn=Not found}\n') ? <ConcertsList /> : null}
      </div>
    )
};

export default connect((state) => ({ concerts: state.concerts })) (Concerts);

然后是列表组件:

import React from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import { withRouter } from 'react-router-dom'
import { saveConcert } from '../.././actions/concerts/concerts'




const ConcertsList = ({concerts, saveConcert}) => {

    const date = (datetime) => {
      return new Date(datetime).toDateString()
    }

    return (

      <div className = "concerts-list">

        {concerts.sort((a, b) => (a.datetime < b.datetime) ? 1 : -1).map(c => <><Link key={c.id} to={`/concerts/${c.id}`}  onClick={()=>saveConcert(c)}>{c.lineup[0]} at {c.venue.name} on {date(c.datetime)}</Link><br/></>)}
      </div> 
    )
}



const mapStateToProps = (state, ownProps) => {
  return {

      concerts: state.concerts
  }
}

export default withRouter(connect(mapStateToProps, {saveConcert})(ConcertsList))

【问题讨论】:

    标签: javascript reactjs asynchronous redux axios


    【解决方案1】:

    这里是如何添加加载微调器或加载栏

    1. 更新您的初始状态以包含加载指示器(例如“isLoading”布尔值。

    const initialState = { isLoading: false, concerts: [], reviews: [] };

    1. 更改您的案例陈述以正确更新每个操作的状态,以下是我的大致做法
    const concertReducer = (state = initialState, action) => {
      switch (action.type) {
        case "LOADING_CONCERTS":
          return { ...state, isLoading: true };
        case "GET_CONCERTS":
          return { ...state,
                   concerts: action.payload,
                   isLoading: false };
        case "ADD_REVIEWS_TO_CONCERTS":
          return { ...state,
                  reviews: action.payload };
    
        default:
          return state;
      }
    };
    
    export default concertReducer;
    
    1. 使用 connect 和 mapStateToProps 将 isLoading 道具引入您的组件
    2. 使用三元运算符检查 'isLoading' 是否为真,并有条件地呈现您的微调器或加载条,如下所示
     {props.isLoading ? (
                    <YourLoadinBarHere' />
                  ) : (
                    <Component or something to render when isLoading is false/>
                  )}
    

    现在,在获取数据时会显示加载栏 (props.isLoading == true) 当然还有其他解决方案,比如使用 HOC 模式,但这是我通常的做法。

    【讨论】:

    • 谢谢!我现在就试一试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    • 2016-05-19
    • 2018-02-16
    相关资源
    最近更新 更多