【问题标题】:Redux state loading, but react not rendingRedux 状态加载,但反应不渲染
【发布时间】:2021-01-17 17:33:42
【问题描述】:

所以我从服务器端获取数据。状态在 redux 中加载,但 react 没有渲染处于状态的数组。

这是我的 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);

【问题讨论】:

  • 您能否为getInvites 提供reducer 并使用redux 开发工具(标签差异)进行截图?
  • getInvites 一个已经绑定到你的 redux store 的函数吗?尝试用connect(mapStateToProps, dispatch =&gt; bindActionCreators({ getInvites }))(InviteModal);替换connect(mapStateToProps, { getInvites })(InviteModal);
  • @KirillSkomarovskiy 完成,我还添加了可以正常工作的代码。
  • @JacobSmit 在尝试您的 getInvites 解决方案时出错:“未提供 'dispatch' 的参数”
  • 抱歉,我离开了一个星期。 bindActionCreators({ getInvites }) 应该包含 dispatch 作为第二个参数 bindActionCreators({ getInvites }, dispatch)

标签: reactjs redux react-redux


【解决方案1】:

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

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

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

您必须决定是要将reduxhooks 一起使用还是class

如果你想将它与钩子一起使用,那么你需要:useSelectoruseActions

如果你想将它与类组件一起使用,那么你需要来自 redux:mapStateToPropsmapDispatchToPropsconnect

简而言之:您正在混合两种不同的方法。

【讨论】:

    【解决方案2】:

    我想你在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;
    

    【讨论】:

    • 这会在我正在渲染的主页上引发各种错误。
    • @morethan1 你能提供屏幕或文字吗?
    • 你是对的,这与我的减速器有关。我为 Invites 创建了单独的减速器和操作,现在一切正常。谢谢
    猜你喜欢
    • 2019-11-19
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 2019-10-06
    • 2018-12-03
    • 1970-01-01
    相关资源
    最近更新 更多