我正在开发我的第一个react / redux Web应用程序,该应用程序从外部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))
答案 0 :(得分:1)
这是如何添加加载微调器或加载栏
const initialState = {
isLoading: false,
concerts: [],
reviews: []
};
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;
3. bring in the isLoading prop to your component using connect and mapStateToProps
4. use ternary operator to check if 'isLoading' is true and conditionally render your spinner or loading bar as follows
{props.isLoading ? (
<YourLoadinBarHere' />
) : (
<Component or something to render when isLoading is false/>
)}
now, your loading bar will be displayed while the data is fetching ('isLoading' is true)
of course there are other solutions like using HOC pattern but this is how I usually do it.