我一直在遵循关于如何使用React和Redux构建服务器端渲染应用程序的精彩类(class),但是现在我处于类(class)无法涵盖并且无法自己弄清楚的情况下。

请考虑以下组件(非常基本,除了底部的导出部分):

class HomePage extends React.Component {

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

    handleLoadMoreClick() {
        this.props.fetchNextHomePagePosts();
    }

    render() {

        const posts = this.props.posts.homepagePosts;
        const featuredProject = this.props.posts.featuredProject;
        const featuredNews = this.props.posts.featuredNews;
        const banner = this.props.posts.banner;
        const data = ( posts && featuredProject && featuredNews && banner );

        if( data == undefined ) {
            return <Loading />;
        }

        return(
            <div>
                <FeaturedProject featuredProject={ featuredProject } />
                <FeaturedNews featuredNews={ featuredNews } />
                <Banner banner={ banner } />
                <PostsList posts={ posts } heading="Recently on FotoRoom" hasSelect={ true } />
                <LoadMoreBtn onClick={ this.handleLoadMoreClick.bind( this ) } />
            </div>
        );

    }

}

function mapStateToProps( { posts } ) {
    return { posts }
}

export default {
    component: connect( mapStateToProps, { fetchHomePageData, fetchNextHomePagePosts } )( HomePage ),
    loadData: ( { dispatch } ) => dispatch( fetchHomePageData() )
};

上面的方法运行良好:loadData函数发出API请求以获取一些数据,该数据通过mapStateToProps函数馈送到组件中。但是,如果我想在同一个loadData函数中激发多个 Action 创建者怎么办?唯一可以做的事情是,如果我编写这样的函数:
function loadData( store ) {
    store.dispatch( fetchFeaturedNews() );
    return store.dispatch( fetchHomePageData() );
}

export default {
    component: connect( mapStateToProps, { fetchHomePageData, fetchNextHomePagePosts } )( HomePage ),
    loadData: loadData
};

但这不是很好,因为我需要返回所有数据...请记住,导出的组件最终会处于以下路由配置中:
const Routes = [
    {
        ...App,
        routes: [
            {
                ...HomePage, // Here it is!
                path: '/',
                exact: true
            },
            {
                ...LoginPage,
                path: '/login'
            },
            {
                ...SinglePostPage,
                path: '/:slug'
            },
            {
                ...ArchivePage,
                path: '/tag/:tag'
            },
        ]
    }
];

以下是一旦特定路线需要组件后如何使用loadData函数:
app.get( '*', ( req, res ) => {

    const store = createStore( req );

    const fetchedAuthCookie = req.universalCookies.get( authCookie );

    const promises = matchRoutes( Routes, req.path ).map( ( { route } ) => {
        return route.loadData ? route.loadData( store, req.path, fetchedAuthCookie ) : null;
    }).map( promise => {
        if( promise ) {
            return new Promise( ( resolve, reject ) => {
                promise.then( resolve ).catch( resolve );
            });
        }
    });

    ...

}

另外,这是 Action 创建者触发的 Action 的示例。他们都兑现 promise :
export const fetchHomePageData = () => async ( dispatch, getState, api ) => {

    const posts = await api.get( allPostsEP );

    dispatch({
        type: 'FETCH_POSTS_LIST',
        payload: posts
    });

}

和 reducer :
export default ( state = {}, action ) => {
    switch( action.type ) {
        case 'FETCH_POSTS_LIST':
            return {
                ...state,
                homepagePosts: action.payload.data
            }
        default:
            return state;
    }
}

最佳答案

因此,您的操作会返回一个Promise,而您正在询问如何返回多个Promise。使用Promise.all:

function loadData({ dispatch }) {
  return Promise.all([
    dispatch( fetchFeaturedNews() ),
    dispatch( fetchHomePageData() ),
  ]);
}

但是...请记住,Promise.all将在所有Promise解析时解析,并且它将返回一个数组值:
function loadData({ dispatch }) {
  return Promise.all([
    dispatch( fetchFeaturedNews() ),
    dispatch( fetchHomePageData() ),
  ]).then(listOfResults => {
    console.log(Array.isArray(listOfResults)); // "true"
    console.log(listOfResults.length); // 2
  });
}

因此,您可能希望以不同的方式处理它。

关于javascript - 如何分派(dispatch)多个 Action 创建者(React + Redux +服务器端渲染),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49559953/

10-13 05:16
查看更多