【问题标题】:How to set state at the server for data from API using react redux如何使用 react redux 在服务器上为来自 API 的数据设置状态
【发布时间】:2018-05-02 06:26:44
【问题描述】:

我正在使用带有 redux 的 react router v4 在服务器上呈现一些数据,但我无法在服务器上设置组件的状态。这是我的代码。感谢帮助

这里是服务器端 loadonserver 函数

loadOnServer({ store, location, routes }).then(() => {
  const context = {};
  const html = renderToString(
    <Provider store={store}>
      <StaticRouter location={location} context={context}>
        <ReduxAsyncConnect routes={routes} />
      </StaticRouter>
    </Provider>
  );

  // handle redirects
  if(context.url) {
    req.header('Location', context.url)
    return res.send(302)
  }

  // render the page, and send it to the client
  res.send(renderLayout(html, '', store.getState(),ApiData , req.protocol + '://' + req.get('x-forwarded-host')));

  // render the page, and send it to the client
  // can't use until redux-connect works with loadable-components
  // getLoadableState(html).then(pageScripts =>
  //   res.send(renderLayout(html, pageScripts.getScriptTag(), store.getState(), !!(req.user && req.user.isAdmin)))
  // )
})
.catch(err => {
  console.log(err);
  res.status(500).end();
});

ApiData 是来自服务器的数据,需要在服务器端设置,以便组件渲染出来

这是我的 index.js

import React from 'react';
import { hydrate } from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import { BrowserRouter, Route } from 'react-router-dom';
import { ReduxAsyncConnect } from 'redux-connect';
import createHistory from 'history/createBrowserHistory';
import { ConnectedRouter, routerMiddleware, push } from 'react-router-redux';

import routes from './routes';
import reducers from './reducers';

import App from './app';

const initialState = window.__INITIAL_STATE;

const history = createHistory();
const middleware = routerMiddleware(history);

const store = createStore(reducers, initialState, applyMiddleware(middleware));

hydrate(
  <Provider store={store}>
    <ConnectedRouter history={history}>
       <ReduxAsyncConnect routes={routes}/>
    </ConnectedRouter>
  </Provider>,
  document.getElementById('app')
);

这是我的 routes.js

import React from 'react';
import App from './app';
import HomePage from './pages/HomePage';

const routes = [{
    component: App,
    routes: [
         {
           path : '/',
           exact: true,
           component: HomePage
         }
    ]
 }];

 export default routes;

这是我的 App.js

import React,  { Component } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import renderRoutes from 'react-router-config/renderRoutes';

import routes from './routes';

import {isBrowser,isServer} from './util/environmentDetection'

class App extends Component {

    constructor(props) {
        super(props);
        if(isServer) {

        } else if(isBrowser && !this.state) {
             this.state = window.__DATA;
             delete  window.__DATA;
        }
     }
     render() {
         return (
             <div>
               <Link to={'/'}>
                {'Home'}
               </Link>
               {renderRoutes(routes[0].routes, { initialData : this.state })}
            </div>
        );
    }
 }

 export default App;

【问题讨论】:

    标签: reactjs redux


    【解决方案1】:

    这是我获取请求状态(打字稿)的方式。但是,我不确定如何从我的操作中获取商店的 req.cookies out,这是完全填充商店所必需的。也许我在这里做错了什么。

    app.get('*', (req, res) => {
        const location = req.url;
        const memoryHistory = createMemoryHistory(req.originalUrl);
        const store = configureStore(memoryHistory);
        const history = syncHistoryWithStore(memoryHistory, store);
    
        match({history, routes, location},
            (error, redirectLocation, renderProps) => {
                if (error) {
                    res.status(500).send(error.message);
                } else if (redirectLocation) {
                    res.redirect(302, redirectLocation.pathname + redirectLocation.search);
                } else if (renderProps) {
                    const asyncRenderData = {...renderProps, store, cookies: req.cookies};
                    loadOnServer(asyncRenderData).then(() => {
                        const css = [];
                        const markup = ReactDOMServer.renderToString(
                            <WithStylesContext onInsertCss={(styles) => css.push(styles._getCss())}>
                                <Provider store={store} key="provider">
                                    <ReduxAsyncConnect {...renderProps} />
                                </Provider>
                            </WithStylesContext>,
                        );
                        try {
                            res.status(200).send(renderHTML(markup, store, css));
                        } catch (err) {
                            res.status(500).send('<pre>' + err + '</pre>');
                        }
                    }).catch((err) => {
                        console.log('sending 404', err);
                        res.status(404).send(x404(JSON.stringify(err || {})));
                    });
                } else {
                    // https://stackoverflow.com/questions/4483849/default-redirect-for-error-404
                    res.status(404).send(x404(null));
                }
            });
    });
    

    【讨论】:

      猜你喜欢
      • 2019-10-02
      • 2016-03-31
      • 2018-09-15
      • 2021-03-26
      • 2017-08-17
      • 2019-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多