如何解决React Redux中的数据加载问题 [英] How to solve data loading issue in React redux

查看:52
本文介绍了如何解决React Redux中的数据加载问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚当数据仍在加载时如何管理/显示该组件.

I am trying to figure out how can i manage/display this component when data is still loading.

在这种情况下,我正在使用react redux.

I am using react redux for this case.

有什么解决方案的建议吗?

any suggestion for solving this out?

尽管我用延迟加载来包装它,但在这种情况下似乎没有什么用.

Although I wrapped this with lazy loading but it seems it is not that much working in this case.

对此有任何建议.

//Actions.js

//Actions.js

export const getContact= () => dispatch => {
    dispatch(setResumesLoading());
    axios
        .get('/api/contacts')
        .then(res => 
            dispatch({
                type: GET_CONTACTS,
                payload: res.data
            })
        ).catch (err => dispatch (returnErrors(err.response.data, err.response.status)));
};

//component.js

//component.js

import React, {Component} from 'react';
import {Grid, Cell, List, ListItem, ListItemContent, Button} from 'react-mdl';
import { connect } from 'react-redux';
import { getContact, deleteContact} from '../../actions/resumeActions';
import PropTypes from 'prop-types';

class Contact extends Component{

    static propTypes = {
        getContact: PropTypes.func.isRequired,
        deleteContact: PropTypes.func.isRequired,
        resume: PropTypes.object.isRequired,
        isAuthenticated: PropTypes.bool,
        auth: PropTypes.object.isRequired
    }

    componentDidMount() {
        this.props.getContact();
    }

    onDeleteContactClick = (id) => {
        this.props.deleteContact(id);
    };

    render(){
        const { contacts } = this.props.resume;
        const { user } = this.props.auth;

        return(
            <div>
                {/* {loading ? <Loading /> : <ResultsComponent results={data} />} */}
                 {contacts.map(({ _id, contact_name, contact_phone, contact_email, contact_skype, contact_image }) => (
            <Grid key={_id} timeout={100} classNames="fade">

               { this.props.isAuthenticated && (user.is_admin === true) ? 
                            <Button className="remove-btn"
                            color="danger"
                            size="sm"
                            onClick= {this.onDeleteContactClick.bind(this, _id)}>
                                &times;
                            </Button> : null }
                    <Cell col={6}>
                        <div style={{textAlign: 'center'}}>
                            <h2> {contact_name} </h2>
                            <img src={contact_image}
                            alt="avatar"
                            style={{height: '40%', borderRadius: '50%', width: '50%'}}
                            img-rounded />
                        </div>

                    </Cell>
                    <Cell col={6} className="contact-right-col text-center">

                        <h2 >Contact Me</h2>
                        <hr  className="resume-left-contact-section-border" />

                        <List>
                          <ListItem>
                            <ListItemContent  className="contact-list-item">
                                <i className="fa fa-phone-square" aria-hidden="true"/>
                                {contact_phone}
                            </ListItemContent>
                          </ListItem>
                        </List>

                    </Cell>
            </Grid>
            ))} 
            </div>


        )
    }
}



const mapStateToProps = (state) => ({
    resume: state.resume,
    isAuthenticated : state.auth.isAuthenticated,
    auth: state.auth
});

export default connect(mapStateToProps, {getContact, deleteContact }) (Contact);

推荐答案

好,您可以在现有操作列表中再添加两个操作.一种用于获取API调用开始状态的信息,另一种用于获取任何错误的信息.像这样:

Well, you can add two more actions into your existing list of actions. One for getting the status of the beginning of the API call and one for any error. Sort of like this:

import * as types from "./actionTypes";

export function beginApiCall() {
  return { type: types.BEGIN_API_CALL };
}

export function apiCallError() {
  return { type: types.API_CALL_ERROR };
}

然后,您可以通过在正确的时间分派这些动作来利用这些动作.

Then you can make use of these actions by dispatching them at the right time.

export const getWorkexperience = () => dispatch => {
    dispatch(beginApiCall());
    axios
        .get('/api/workexperiences')
        .then(res => 
            dispatch({
                type: GET_WORKEXPERIENCE,
                payload: res.data
            })
        ).catch (err => dispatch(apiCallError(error)););
};

然后,您必须为此操作创建一个新的减速器.为此编写减速器有些棘手.您需要存储进行中的API调用的数量,并根据其状态增加或减少它们.为此,您可以在所有动作创建者和还原者中将_SUCCESS附加到现有动作类型中.

Then you have to create a new reducer for this action. Writing a reducer for this is a little tricky. You need to store the number of API calls in progress and increment or decrement them based on their status. For that, you can append _SUCCESS to your existing action type in all your action creators and reducers.

import * as types from "../actions/actionTypes";
import initialState from "./initialState";

function actionTypeEndsInSuccess(type) {
  return type.substring(type.length - 8) === "_SUCCESS";
}

export default function apiCallStatusReducer(
  state = initialState.apiCallsInProgress,
  action
) {
  if (action.type == types.BEGIN_API_CALL) {
    return state + 1;
  } else if (
    action.type === types.API_CALL_ERROR ||
    actionTypeEndsInSuccess(action.type)
  ) {
    return state - 1;
  }

  return state;
}

  //initialState.js
    export default {
      state1: [],
      state2: [],
      apiCallsInProgress: 0
    };

一旦在组件内部,发出提取请求后,就可以使用此化简器的状态来渲染微调器或所需的任何东西,只需从化简器中获取它即可.

Once inside your component, after you make a fetch request, you can use the state of this reducer to render a spinner or anything you want just by fetching it from the reducer.

  const loading = useSelector((state) => state.apiCallsInProgress > 0);

或者您可以通过mapStateToProps这样访问它,我看到您以前已经在组件中获取道具.

or you can access it via mapStateToProps like this, which I see you have used to fetch props in your component.

const mapStateToProps = (state) => ({
    resume: state.resume,
    isAuthenticated : state.auth.isAuthenticated,
    auth: state.auth,
    loading: state.apiCallsInProgress > 0
});

您可以像这样返回函数的内容.

And you can return the content of the function like this.

 {loading ? (
       Loading...
      ) : (
        <div>My component</div>
)}

这篇关于如何解决React Redux中的数据加载问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆