【问题标题】:React server side rendering using data called from API使用从 API 调用的数据反应服务器端渲染
【发布时间】:2017-02-14 16:46:35
【问题描述】:

我使用 react-redux + thunk + redial 并在服务器端生成我的 HTML。我想通过 react-helmet 使用来自另一台服务器的用户数据生成元标记。 在我的服务器中:

import { trigger } from 'redial';
trigger('fetch', components, locals)
      .then(() => {
          const state = getState();
          var html = ReactDOMServer.renderToString (
              <Provider store={store} key="provider">
                  <ReactRouter.RouterContext {...renderProps} />
              </Provider>
          );
let head = Helmet.rewind();
response.send(`<!DOCTYPE html>
              <head>
                <meta charSet="UTF-8"></meta>
                <meta httpEquiv="X-UA-Compatible" content="IE=edge,chrome=1"></meta>
                <meta name="viewport" content="width=device-width, initial-scale=1"></meta>
                <link rel='stylesheet' href='/css/bootstrap.css'/>
                ${style? "<style>"+style+"</style>" : "<link rel='stylesheet' href='/css/app.css'/>"}
                    ${head.title}
                    ${head.meta}
                    ${head.link}
                    ${head.script}
                </head>
                <body>
                  <div id="app">${html}</div>
                  <script src='/javascript/bundle.js'></script>
                     ${popUp}
                </body>
              </html>`);

在我的组件中,我在 render() 函数中调用 dispatch 以在操作文件中运行一个函数,该函数调用 API 并返回用户数据。无论我在哪里使用调度,它都有相同的结果。在最好的情况下,React 返回请求并等待来自其他服务器的数据。但由于我设置为检查从服务器接收到的数据的条件,它没有返回任何内容。

我的组件

    var profile=[], shouldRender = false
export var Profile = React.createClass({
render () {
  var {x,y,z} = this.props;
  var pathArray = (this.props.path).split( '/' );
  if(!canUseDOM && shouldRender == false)dispatch(
    actions.theProfile(x,y,z)
  ).then((es) => {profile = es; shouldRender= true;Promise.resolve()})
  .catch((et) => console.log("error"));

if(shouldRender){
  console.log("got inside");
  return (
    <div  className="container">
      <RightSideBar page="profile"/>
      <Helmet
            title={metaData('title', name, profileId)}/>
      <div className="col-md-6 col-xs-12 col-md-offset-3 content right">
        <div className="row">
          {profileContent(ideaTypes)}
        </div>
      </div>
      <div className="col-md-3 col-xs-12 sidebar-left hidden-xs hidden-sm hidden-md">
        <LeftSideBar page="profile"/>
      </div>
    </div>
  )
 }
});

以及我使用 axios 调用 API 的操作

    export var viewingProfile = (ux,y,z) => {
    return function (dispatch, getState)  {
      return axios.post(root + '/api/getUser', {
          Id: x,
          orgid: y,
          profileId: z
      })
      .then(function (res) {
        if(res.data.statusEntity.statusCode == -201){
          window.location.href = "/user-not-found"
        } else {
          dispatch(updateState(res.data))
          return res.data;

        }
      })
    }
  }

【问题讨论】:

    标签: reactjs redux react-redux redux-thunk


    【解决方案1】:

    render() 方法中调用 dispatch 是错误的做法,因为 render 方法应该是不可变的。用redial 提供的钩子包裹你的组件来解析数据api。请参考redial repo 中的示例用法。

    【讨论】:

    • 我应该这样做,我在写完这个问题后注意到了,但我没有测试过。我明天再做,希望能解决问题
    • 我做到了,但问题仍然存在。它甚至没有调用动作。
    【解决方案2】:

    终于在react服务器端渲染中对来自另一台服务器的数据进行了大量渲染工作后,我找到了最佳解决方案。 首先,您不需要重拨,这是多余的,至少在我的情况下是这样。所以我从我的源代码中删除了它。 然后,我搬家了

    dispatch(
     actions.theProfile(x,y,z)
    )
    

    到我的路线

    export default (store) => {
     const requireApiCall= (nextState, replace, cb) => {
      var state = store.getState();
        return store.dispatch(actions.theProfile(x,y,z)).
        then(()=>{
          cb()
        })
    
     };
     <Route path="/" component={App}>
       <IndexRoute  component={Home}/>
       <Route path="profile" component={Profile } onEnter={requireApiCall}>
       </Route>
     </Route>
    }
    

    调度将执行,路由等待回调“cb()”,当我的 API 调用得到应答时,我的商店会使用接收到的数据进行更新。然后 action 解析 promise,然后 requireApiCall 中的 promise 解析并返回回调“cb()”。路由开始渲染组件,发送给客户端的答案将使用接收到的数据生成。

    我知道这有点复杂,但效果很好。

    【讨论】:

      猜你喜欢
      • 2017-10-04
      • 2019-02-09
      • 2018-10-02
      • 2017-01-14
      • 2018-02-16
      • 1970-01-01
      • 2016-02-05
      • 1970-01-01
      • 2015-05-09
      相关资源
      最近更新 更多