Redux状态加载,但不响应

时间:2020-10-02 00:25:41

标签: reactjs redux react-redux

所以我正在从服务器端获取数据。状态正在redux中加载,但react不会呈现处于状态的数组。

这是我的反应:

import React, { useEffect, useState } from "react";
import { IonContent, IonButton, IonButtons, IonToolbar, IonTitle, IonHeader,  IonList } from "@ionic/react";
import { IInviteModal, IInviteReduxProps } from "../types/interfaces";
import { connect } from "react-redux";
import {getInvites} from '../flux/actions/eventActions';
import InviteListItem from "./InviteListItem";

const InviteModal = ({ getInvites, invite, onDismissModal}: IInviteModal) => {
  
// const [invites, setInvites] = useState();

  useEffect(() => { 
    getInvites(); 
  }, [getInvites]);

  // const { invites } = invite;
  const {invites}  = {...invite}

  const handleOnSubmit = (e: any) => {
      e.preventDefault();
 };
    
  return (
        <IonContent>
          <form onSubmit={handleOnSubmit}>
              <IonHeader>
              <IonToolbar>
                <IonButtons slot="start">
                    <IonButton 
                    onClick={onDismissModal}
                    >
                        Back
                    </IonButton>
                </IonButtons>
              <IonTitle>
                <div className="ion-text-center">
                Event Invites
                </div>
              </IonTitle>
            </IonToolbar>
            </IonHeader>
            <IonList>
                {
                invites ? 
                invites.map(invite => <InviteListItem 
                invite={invite}
                key={invite._id}
                />
                )
                : "Loading..."
              }
            </IonList>
          </form>
          </IonContent>
  );
};

const mapStateToProps = (state: IInviteReduxProps) => ({
  invite: state.invite
});

export default connect(mapStateToProps, { getInvites })(InviteModal);

import React from 'react';
import {  IonItem, IonLabel, IonButton, IonGrid, IonRow, IonCol } from '@ionic/react';
import {connect} from 'react-redux';
import {setCurrentI} from '../flux/actions/eventActions';
import { IInviteListItem } from '../types/interfaces';
import {format} from "date-fns";
 
const InviteListItem = ({ invite, setCurrentI }: IInviteListItem) => {

  const setCurrentInvite = (invite: any) => {setCurrentI(invite)};

  return (
          <div>          
              <IonItem
              onClick={() => setCurrentInvite(invite)}
              >
                <IonLabel>
                <h2>{invite.title}</h2>
                <p>{invite.location}</p>
                <br />
                <p>{format(new Date(invite.dateStart), "MMM d', 'h:mm aaa")}&mdash;&nbsp;
                  {format(new Date(invite.dateEnd), "MMM d', 'h:mm aaa")}</p>
                  {/* <br /> */}
                  <div className="ion-text-center">
                <IonGrid>
                  <IonRow>
                    <IonCol>
                      <IonButton size="small" fill="clear">
                      Accept
                      </IonButton>
                    </IonCol>
                    <IonCol>
                      <IonButton size="small" fill="clear">
                      _
                      </IonButton>
                    </IonCol>
                    <IonCol>
                      <IonButton size="small" fill="clear">
                      Decline
                      </IonButton>
                    </IonCol>
                  </IonRow>
                </IonGrid>
                </div>
                </IonLabel>
              </IonItem>
        </div>      
  );
};

export default connect(null, {setCurrentI})(InviteListItem);

这是减速器:

import {GET_EVENTS, GET_EVENT, ADD_EVENT, DELETE_EVENT, EVENTS_LOADING, UPDATE_EVENT, SET_CURRENT, CLEAR_CURRENT, LOG_ARRIVAL, EVENT_ERROR, GET_INVITES} from '../actions/types';
import {IAction, IEvent, IInvite} from '../../types/interfaces';

const initialState = {
    events: [],
    invites: [],
    current: [],
    loading: false
};

interface IState {
    events: IEvent[];
    invites: IInvite[];
  }
  
export default function(state: IState=initialState, action: IAction){
    switch(action.type){
        case GET_EVENTS:
            return{
                ...state,
                events: action.payload,
                loading: false
            };
        case GET_INVITES:
            return{
                ...state,
                invites: action.payload,
                loading: false
            };
}

Page not mapping array, state is loaded Diff redux output

页面仅显示“正在加载...”

奇怪的是,我正在使用完全相同的结构来获取其他数据,并且数组映射没有问题。

关于如何获取数组的任何想法吗?

这是起作用的代码:

import React, { useEffect } from 'react';
import { IonContent, IonLabel, IonList } from '@ionic/react';
import {connect} from 'react-redux';
import {getEvents} from '../flux/actions/eventActions';
import { IEventReduxProps, ICalendar } from '../types/interfaces';
import EventListItem from './EventListItem';


const Calendar = ({ getEvents, event }: ICalendar) => {

  useEffect(() => { 
    getEvents(); 
  }, [getEvents]);
 
  const { events } = event;

  return (
    <IonContent>
      <IonList>
          {events.map(event => <EventListItem 
          event={event} 
          key={event._id}/>
          )
          }
      </IonList>
    </IonContent>
  );
};

const mapStateToProps = (state: IEventReduxProps) => ({
  event: state.event
});

export default connect(mapStateToProps, { getEvents })(Calendar);

import React from 'react';
import {  IonItem, IonIcon, IonLabel, IonButton } from '@ionic/react';
import {connect} from 'react-redux';
import {deleteEvent, setCurrent} from '../flux/actions/eventActions';
import { IEventListItem } from '../types/interfaces';
import { closeCircle } from 'ionicons/icons';
import {format} from "date-fns";

const EventListItem = ({ event, deleteEvent, setCurrent }: IEventListItem) => {

  const handleDelete = (_id: string) => {deleteEvent(_id);};
  const setCurrentEvent = (event: any) => {setCurrent(event);};

  return (
          <div>          
              <IonItem  
              onClick={() => setCurrentEvent(event)}
              // routerLink={`/event/${event._id}`}          
              >
                <IonLabel>
                <h2>{event.title}</h2>
                <p>{event.location}</p>
                <p>{format(new Date(event.dateStart), "MMM d', 'h:mm aaa")}&mdash;&nbsp;
                  {format(new Date(event.dateEnd), "MMM d', 'h:mm aaa")}</p>
                  {/* MAP the ATTENDEES */}
                  {event.attendees.map((attendee, _id)=> (
                  <p key={attendee._id} >
                    {attendee.name}
                    {/* {attendee.email} */}
                  </p>
                  )
                  )}
                </IonLabel>
                <IonButton
                routerLink={`/event/log/${event._id}`}
                color="success"
                fill="clear"
                >Log</IonButton>
                
                <IonButton
                routerLink={`/event/${event._id}`}
                fill="clear"
                >Edit</IonButton>
                <IonIcon 
                    icon={closeCircle} 
                    slot="end"
                    className="remove-btn"
                    color="danger"
                    onClick={() => handleDelete(event._id)}
                    />
              </IonItem>
        </div>      
  );
};



export default connect(null, { deleteEvent, setCurrent })(EventListItem);

2 个答案:

答案 0 :(得分:0)

如果您在redux store中有数据,则必须从useSelector()中添加react-redux

这样,当新的props进入应用程序时,您将通知组件,这将导致组件使用新数据re-render

还有一个问题是导致您同时使用import { connect } from "react-redux";hooks

您必须确定要结合reduxhooks使用class

如果要与挂钩一起使用,则需要:useSelectoruseActions

如果您想将其与类组件一起使用,则需要在redux中使用:mapStateToPropsmapDispatchToPropsconnect

简短地说:您正在混合两种不同的方法。

答案 1 :(得分:0)

我想您对connect遇到了一些问题。 HOC connect有4个参数。特殊的options 我尚未确定您的问题。您可以尝试以下两个组件吗?

如果此代码无济于事-我认为您在减速器,操作,中间件方面存在问题。

InviteModal.tsx

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { IonContent, IonButton, IonButtons, IonToolbar, IonTitle, IonHeader,  IonList } from '@ionic/react';

import { getInvites } from '../flux/actions/eventActions';

import { IInviteModal, IInviteReduxProps } from '../types/interfaces';
import InviteListItem from './InviteListItem';
/* TODO: make correct IInviteModal */
const InviteModal: React.FC<IInviteModal> = ({ onDismissModal }) => {
  const dispatch = useDispatch();
  const { invites } = useSelector(({ invite }: IInviteReduxProps) => invite);

  React.useEffect(() => { 
    dispatch(getInvites());
  }, [dispatch]);

  const handleOnSubmit = React.useCallback((e: any) => {
    e.preventDefault();
  }, []);
    
  return (
    <IonContent>
      <form onSubmit={handleOnSubmit}>
        <IonHeader>
          <IonToolbar>
            <IonButtons slot="start">
              <IonButton onClick={onDismissModal}>
                Back
              </IonButton>
            </IonButtons>
            
            <IonTitle>
              <div className="ion-text-center">
                Event Invites
              </div>
            </IonTitle>
          </IonToolbar>
        </IonHeader>

        <IonList>
          {
          invites
            ? invites.map(invite => <InviteListItem invite={invite} key={invite._id} />)
            : "Loading..."
          }
        </IonList>
      </form>
    </IonContent>
  );
};

export default InviteModal;

InviteListItem.tsx

import React from 'react';
import {  IonItem, IonLabel, IonButton, IonGrid, IonRow, IonCol } from '@ionic/react';
import { useDispatch } from 'react-redux';
import { format } from 'date-fns';

import { setCurrentI } from '../flux/actions/eventActions';

import { IInviteListItem } from '../types/interfaces';

const formatData = (data: string) => format(new Date(data), "MMM d', 'h:mm aaa");
/* TODO: make correct IInviteListItem */
const InviteListItem: React.FC<IInviteListItem> = ({ invite }) => {
  const dispatch = useDispatch();
  const setCurrentInvite = React.useCallback(() => {
    dispatch(setCurrentI(invite));
  }, [invite, dispatch]);

  return (
    <IonItem onClick={setCurrentInvite}>
      <IonLabel>
        <h2>{invite.title}</h2>
        
        <p>{invite.location}</p>
        
        <br />
        
        <p>
          {formatData(invite.dateStart)}
          &mdash;&nbsp;
          {formatData(invite.dateEnd)}
        </p>

        <div className="ion-text-center">
          <IonGrid>
            <IonRow>
              <IonCol>
                <IonButton size="small" fill="clear">
                  Accept
                </IonButton>
              </IonCol>

              <IonCol>
                <IonButton size="small" fill="clear">
                  _
                </IonButton>
              </IonCol>
              
              <IonCol>
                <IonButton size="small" fill="clear">
                  Decline
                </IonButton>
              </IonCol>
            </IonRow>
          </IonGrid>
        </div>
      </IonLabel>
    </IonItem>
  );
};

export default InviteListItem;