使用React Hooks和Redux获取数据

时间:2020-06-15 03:10:34

标签: reactjs react-redux react-hooks

我目前正在尝试使用以下方法从后端获取数据。我正在尝试将每个事件项分解为一个eventIndexItem组件,但是在useEffect之后事件仍未定义。

import React, { useState, useEffect } from 'react'
import EventIndexItem from './event_index_item'
import 'react-modern-calendar-datepicker/lib/DatePicker.css';
import { Calendar, utils } from 'react-modern-calendar-datepicker';

const EventIndex = ({ searchValue, fetchEvents }) => {
    let today = utils().getToday()
    const [ selectedDay, setSelectedDay ] = useState(today)

    function dateFormatter (selectedDay) {
        return selectedDay.month + " " + selectedDay.day
    }

    let formattedDate = dateFormatter(selectedDay)

    let events
    useEffect (() => {
        events = fetchEvents()
    }, [] )

    function handleEvents () {
        const filterEvents = events.filter(event => {
            let title = event.title
            if ( searchValue === "" || title.includes(searchValue) ) {
                return true
            } else {
                return false
            }
        })

        return filterEvents.map(event => (
            <EventIndexItem 
                key={event.id}
                event={event}
            />
        ))
    }


    return (

        <div className='event-index-container'>
            <div className='event-index-left'>
                <h1 className="event-index-date"> { formattedDate } </h1>
                { handleEvents() }
            </div>
            <div className='event-index-right'>
                <Calendar 
                    calendarClassName="event-index-calendar"
                    value={selectedDay}
                    onChange={setSelectedDay}
                    colorPrimary={'#00a2c7'}
                />
            </div>
        </div>
    )
}

export default EventIndex

Redux容器看起来像这样。

import { connect } from 'react-redux'
import EventIndex from './event_index'
import { fetchEvents } from '../../action/event_actions'

const msp = (state, ownProps) => {
    let searchValue = ownProps.searchValue
    return ({
        events: Object.values(state.entities.events),
        searchValue,
        currentUser: state.entities.users[state.session.id]
    })
}

const mdp = dispatch => {
    return ({
        fetchEvents: () => dispatch(fetchEvents())
    })
}

export default connect (msp, mdp) (EventIndex)

动作/暴徒

import * as EventAPIUtil from '../util/event_api_util';
import * as RSVPApiUtil from '../util/rsvp_api_util';

export const RECEIVE_EVENTS = "RECEIVE_EVENTS";
export const RECEIVE_EVENT = "RECEIVE_EVENT";
export const REMOVE_EVENT = "REMOVE_EVENT";

const receiveEvents = ( events ) => {
    return ({
        type: RECEIVE_EVENTS,
        events
    });
};

export const fetchEvents = () => (dispatch) => (
    EventAPIUtil.fetchEvents().then(events => dispatch(receiveEvents(events)))
);

减速器

import {
    RECEIVE_EVENTS,
    RECEIVE_EVENT,
    REMOVE_EVENT
} from '../action/event_actions';


const eventsReducer = (state = {}, action) => {
    Object.freeze(state);
    let newState;
    switch (action.type) {
        case RECEIVE_EVENTS:
            return action.events;
        case RECEIVE_EVENT:
            newState = Object.assign({}, state, { [action.event.id]: action.event });
            return newState;
        case REMOVE_EVENT:
            newState = Object.assign({}, state)
            delete newState[action.eventId]
            return newState;
        default:
            return state;
    }
};

export default eventsReducer; 

我以前创建了一个在this.props.fetchEvents()中调用componentDidMount的类组件,然后在渲染中调用我的handleEvents()没问题。但是,变量事件是不确定的,但是我确实看到事件通过redux-logger添加到redux状态。请指教!也可以随意评论当前代码。

1 个答案:

答案 0 :(得分:2)

有两种方法可以解决此问题。您可以:

  • 从React组件获取(不推荐)

为此,您需要对代码进行一些重构

  1. 所有API调用函数都应包装在Promise中。
  2. 您必须通过操作分派将结果添加到Redux状态
  3. 您将在useEffect中使用异步回调函数
  4. 您需要将抓取条件包装起来,以检查状态中是否已经存在值。

为什么我不推荐:

因为您正在混合业务状态和UI状态。 Redux通过管理Redux中的业务状态和React中的UI状态来帮助区分这一点。因此,请始终避免将它们混合在一起。

  • 从Redux发送异步操作(推荐)
    1. 使用Redux thunk进行异步操作。
    2. useEffect派发动作
    3. 从reducer进行API调用。
    4. 在调用之前在减速器中设置条件。

请注意,您必须设置条件以进行API调用并更新状态,否则React组件将继续重新渲染。

为什么我推荐:

它将业务状态与UI状态分开。

  • 实施推荐方法的一种方式。

createSlice对于自动生成动作创建者,Reducer和选择器。

createAsyncThunk用于在Redux中使用API​​。

React Redux template官方模板,用作设置示例。