如何在 Redux api 调用期间在组件上设置加载布尔值



我正在创建一个基于 React、Redux 和 Redux-Thunk 的项目。

在下面的示例中,我列出了每个"项目",并允许用户"增量"(对 API 进行 1 秒的虚假调用(并更新 MainApp 组件上的状态(以显示加载(

问题:incrementProject操作直接完成到主应用程序组件中时,如何捕获?

我搜索了很多关于它的信息,但没有找到任何东西。处理此类案件的最佳方法是什么?

想法:

  • 将所有状态创建到 Redux 项目存储中并全局处理所有加载状态?(我担心代码会更重:/(

  • incrementProject(projectId, next)发送回调,并在调度错误或成功后从操作中调用它?


我没有包括所有动作/化简器/api调用,因为它是非常基本的代码。

主应用组件

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect, Provider } from 'react-redux';
import { requestProjects, incrementProject } from '../actions';
class MainApp extends Component {
constructor(props) {
super(props);
this.state = { loadingProjectsIds: [] };
}
componentDidMount() {
const { requestProjects } = this.props;
requestProjects();
}
render() {
const { projectStore, incrementProject } = this.props;
const { loadingProjectsIds } = this.state;
const incrementProject = (project) => {
let ids = this.state.loadingProjectsIds;
ids.push(project._id);
this.setState({
loadingProjectsIds: ids
});
incrementProject(project._id);
}
return (
<ul>
{projectStore.projects.map(project => (
<li key={`project-${project.key}`}>
{project.name} 
{
loadingProjectsIds.indexOf(project._id) !== -1) 
? Incrementing...
: <a>Increment</a>
}
</li>
))}
</ul>
);
}
};
export default connect((state) => { project } = state), (dispatch) => ({
requestProjects: () => dispatch(requestProjects()),
incrementProject: (_id) => dispatch(incrementProject(_id)),
})(MainApp);

增量操作

export function incrementProject(projectId) {
return async dispatch => {
dispatch({type: 'PROJECT_INC', projectId});
let { err, payload } = await API.incProject({projectId});
if (err) {
dispatch({type: 'PROJECT_INC_ERR', err});
}
else {
dispatch({type: 'PROJECT_INC_SUCCESS', payload});
}
};
};

没有最好的解决方案。一切都取决于谁对发送给定action感兴趣。一种更通用的方法(我们使用(是在减速器中具有TOGGLE_LOADING操作和loading属性。像这样的东西

const initialState = {
value : '',
loading: false,
error: false
}
export const reducer = (state = initialState, action) =>{
switch(action.type){
case 'TOGGLE_LOADING' : return{
...state,
loading : !state.loading
}
case 'STORE_VALUE' : return{
...state,
loading: false
}
case 'ERROR_FETCHING' : return{
...state,
loading : false,
error: true,
}
default : return state
}
}

在你的action creator

const fetchValue = () =>{
return dispatch =>{
dispatch({type: 'TOGGLE_LOAD'})
apiCall()
.then(value =>{
dispatch({type: 'STORE_VALUE'})
})
.catch(error =>{
dispatch({type: 'FETCH_ERROR'})
})
}
}

现在,您已在state中配置了一个loading属性。只需在组件中使用它即可

class Component extends React.Component{
componentDidMount(){
fetchValue()
}
render(){
const { loading } = this.props
return loading ? 'Loading' : <Content />
}
}

最新更新