簡體   English   中英

React 功能組件,Redux 和加載數據

[英]React Functional Component, Redux and Loading Data

我目前正在嘗試獲取功能性反應,並且很難找出在頁面加載時從 API 加載數據的適當方法。 我正在使用反應,redux 和 thunk。 我已經修改了我從本課程創建的項目。 我的代碼目前看起來像這樣

store.js

import {createStore, applyMiddleware, compose} from "redux";
import rootReducer from "./reducers";
import reduxImmutableStateInvariant from 'redux-immutable-state-invariant';
import thunk from "redux-thunk";


export default function configureStoreDev(initialState){

    const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; // add support for redux dev tools

    return createStore(
        rootReducer,
        initialState,
        composeEnhancers(applyMiddleware(thunk, reduxImmutableStateInvariant()))
    );
}

作者Api.js

import { handleResponse, handleError } from "./apiUtils";
const baseUrl = process.env.API_URL + "/authors/";

export function getAuthors() {
  return fetch(baseUrl)
    .then(handleResponse)
    .catch(handleError);
}

作者Actions.js

import * as actionTypes from "./actionTypes";
import * as authorApi from "../../api/authorApi";
import {apiCallError, beginApiCall} from "./apiStatusAction";


export function loadAuthorsSuccess(authors){
    return {type: actionTypes.LOAD_AUTHORS_SUCCESS, authors: authors};
}

export function loadAuthors(){
    return function(dispatch){

        // invoke loader
        dispatch(beginApiCall());

        return authorApi.getAuthors().then(response => {
            dispatch(loadAuthorsSuccess(response.authors));
        }).catch(error => {
            dispatch(apiCallError());
            throw error;
        })
    }
}

作者Reducer.js

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

export default function authorReducer(state = initialState.authors, action){
    switch(action.type){
        case actionTypes.LOAD_AUTHORS_SUCCESS:
            return action.authors;
        default:
            return state;
    }
}

AuthorsPage.js

import React, {useState, useEffect} from 'react';
import {connect} from 'react-redux';
import AuthorsList from "./AuthorsList";
import Spinner from "../common/Spinner";

import {loadAuthors} from "../../redux/actions/authorActions";
import {loadCourses} from "../../redux/actions/courseActions";

function AuthorsPage({loadAuthors, deleteAuthor, loadCourses, ...props}) {
    const [authors, setAuthors] = useState([...props.authors]);
    const [courses, setCourses] = useState([...props.courses]);
    const [loading, setLoading] = useState(props.loading);
    const [redirectToAddAuthorPage, setRedirectToAddAuthorPage] = useState(false);

    useEffect(() => {
        loadAuthors().catch(error => {
            console.log("Loading authors failed: " + error);
        });
        loadCourses().catch(error => {
            console.log("Loading courses failed: " + error);
        });
    }, []);

    useEffect(() => {
        if(authors !== props.authors && props.authors.length > 0){
            setAuthors([...props.authors]);
        }
    }, [props.authors]);

    useEffect(() => {
        setLoading(props.loading)
    }, [props.loading]);



    return (
        <>
            <h2>Authors</h2>
            {loading === true ? <Spinner/> : (
                <>
                    <button
                        style={{ marginBottom: 20 }}
                        className="btn btn-primary add-course"
                        onClick={() => setRedirectToAddAuthorPage(true )}
                    >
                        Add Author
                    </button>
                    <AuthorsList authors={authors}  />
                </>
            )}

        </>
    );
}

function mapStateToProps(state){
    return {
        authors: state.authors,
        courses: state.courses,
        loading: state.apiCallsInProgress > 0

    }
}
const mapDispatchToProps = {
    loadAuthors: loadAuthors,
    loadCourses: loadCourses
}

export default connect(mapStateToProps, mapDispatchToProps)(AuthorsPage);

我遇到問題的部分是讓作者列表正確設置 state。 我嘗試在調用loadAuthors()之后設置它,但沒有在該調用的 .then( .then()中返回作者列表。

下一個選項是使用useEffect監聽作者的 props 變化,但這似乎不是加載我在初始加載時需要的數據的最有效或正確的方法。

我似乎無法找到任何文章或教程,詳細說明從功能組件的角度完成此任務的適當方法,並且希望在正確方向上提供任何指導或指示。

下一個選項是使用 useEffect 監聽作者的 props 變化,但這似乎不是加載我在初始加載時需要的數據的最有效或正確的方法。

您可以直接渲染props.authors而無需將其分配給useState

例子

 const thunk = ReduxThunk.default; const { connect, Provider } = ReactRedux; const { bindActionCreators, combineReducers, createStore, applyMiddleware } = Redux; window.redux = Redux; const initialState = { authors: [] }; const getAuthors = () => Promise.resolve(Array(10).fill(0).map((pr, index) => ({id: index, name: `Author ${index + 1}`}))) const loadAuthorsSuccess = (authors) => { return {type: 'LOAD_AUTHORS_SUCCESS', authors}; } const loadAuthors = () => { return function(dispatch) { return getAuthors().then(authors => { dispatch(loadAuthorsSuccess(authors)); }) } } const authorReducer = (state = initialState.authors, action) => { switch(action.type) { case 'LOAD_AUTHORS_SUCCESS': return action.authors; default: return state; } } const reducer = combineReducers({ authors: authorReducer}) const store = createStore( reducer, initialState, applyMiddleware(thunk) ); const { useState, useEffect } = React; function mapStateToProps({authors}) { return { authors } } const mapDispatchToProps = { loadAuthors } const _AuthorsPage = ({loadAuthors, authors}) => { useEffect(() => { loadAuthors().catch(error => { console.log("Loading authors failed: " + error); }); }, []) return <div> {authors.map(({id, name}) => <div key={id}>{name}</div>)} </div> } const AuthorsPage = connect(mapStateToProps, mapDispatchToProps)(_AuthorsPage) const App = () => { return <div> <AuthorsPage/> </div> } ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );
 <script src="https://unpkg.com/react/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <script src="https://unpkg.com/redux@4.0.5/dist/redux.js"></script> <script src="https://unpkg.com/react-redux@latest/dist/react-redux.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/redux-thunk/2.3.0/redux-thunk.js"></script> <div id="root"></div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM