javascript - react redux 服务端渲染 server如何根据不同路由dispatch不同的action

查看:141
本文介绍了javascript - react redux 服务端渲染 server如何根据不同路由dispatch不同的action的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

react redux 服务端渲染 server如何根据不同路由dispatch不懂的action

match({routes: routes(store.getState()), location: req.url}, (err, redirectLocation, renderProps) => {
        if (err) {
            res.status(500).end(`Internal Server Error ${err}`);
        } else if (redirectLocation) {
            res.redirect(redirectLocation.pathname + redirectLocation.search);
        } else if (renderProps) {
            Promise.all([
                    // loginManage()
                    store.dispatch(fetchGetCitys())
                ])
                .then(() => {
                    console.info('zzzzzzzzzzzzzzz',store.getState())
                    const html = renderToString(
                        <Provider store={store}>
                            <RouterContext {...renderProps} />
                        </Provider>
                    );
                    //res.end(renderFullPage(html, store.getState()));
                    res.render('index', {
                        __html__: html,
                        __state__: JSON.stringify(store.getState())
                    })
                });
        } else {
            res.status(404).end('Not found');
        }
    });
    
    //在响应客户端之前 我dispatch了fetchGetCitys这个action 但是如何根据不同的路由dispatch不同的action呢?

解决方案

需要在组件上定义一个方法用于在服务端渲染时调用获取数据:

class ArticleContainer extends Component {
    constructor(props) {
        super(props);
    }

    // 用于服务端渲染获取数据
    static fetchData(dispatch, params) {
        return dispatch(getArticle(params.id, prefix));
    }

    componentDidMount() {
        const { params, dispatch, getArticle } = this.props;
        dispatch(getArticle(params.id));
    }

    render() {
        const { article } = this.props;

        if (article) {
            return <Article post={article} />
        }
        return (<div>loading...</div>);
    }
}

match 的回调函数中有一个 renderProps,renderProps.components 可以得到当前 router 的所有组件。

// 创建 store
const store = configureStore();

// 遍历组件,其中 WrappedComponent 就是其原始组件
let coms = renderProps.components.map(c => c.WrappedComponent);

// 我们只需要得到定义了 fetchData 方法的组件
let coms = renderProps.components.filter(c => !!c.WrappedComponent.fetchData);
// 提取所有 fetchData
let fetchs = coms.map(c => c.WrappedComponent.fetchData);

// 然后执行所有 fetchData
let tasks = [];
fetchs.map(f => {
    let t = f(store.dispatch, renderProps.params);
    if (Array.isArray(t)) {
        tasks = tasks.concat(t);
    } else {
        tasks.push(t);
    }
});

// 封装为 promise 任务
let taskPromise = Promise.all(tasks);

taskPromise.then(() => {
    // 可以渲染组件了
    const html = renderToString(
        <Provider store={store}>
            <RouterContext {...renderProps} />
        </Provider>
    );
});

大概就是这样。

这篇关于javascript - react redux 服务端渲染 server如何根据不同路由dispatch不同的action的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆