2

I have created a website which is React+Redux Serverside Render app, for loading server data I am dispatching an action on componentWillMount but it is an asynchronous request which loading data from AWS and it takes 2-3 seconds to respond unfortunately google content crawler doesn't crawl content which is highly required. So I need to make an approach to set server data for redux initial state, so that It can open web app with full content but I am not getting how to achieve this here my code.

Store.js

import {createStore, combineReducers} from 'redux'
import {GET_CARDS} from '../actions/cardsAction';

//here is my reducer
function mycards(state={},{type,payload}){
    switch(type){
        case GET_CARDS :  return {data:" test mydata"};
        default : return state;
    }
}

const allreducer = combineReducers({
    cards: mycards
})

export const configurestore=(initState)=>{

    const store = createStore(
        allreducer,
        initState
    )
    return store;
}

here is my Action.js

import dataloader from '../server/dataloader';
export const GET_CARDS ='GET_CARDS';

export function getcards(){

    return async (dispatch) =>{

 //Dataloader is another module which returns Aws server data it is working fine

        let _serverdata = await dataloader()        
            dispatch({
                type:GET_CARDS,
                payload:{
                    data:_serverdata
                }
            })
    }
}

Server.js

import {Provider} from 'react-redux';
import {configurestore,datasetter} from './store/store';
const port = process.env.PORT || 8080;
const server = express();

..other express code

server.get('*', (req, res, next) => {

  const context = {data};
  const store = configurestore();
  const jsx = (
            <Provider store={store}>
              <StaticRouter context={context} location={req.url}>
                  <Template />
              </StaticRouter>
            </Provider>
        );

        const reactDom = renderToString(jsx);

        res.writeHead( 200, { "Content-Type": "text/html" } );
        res.end( htmlTemplate(reactDom,data) );

    }).catch(next)
})


function htmlTemplate( reactDom,data ) {
  return `basic html code`;
}

here is my index.js

import React from "react";
import { hydrate } from "react-dom"
import App from "./client/App";
import { BrowserRouter } from "react-router-dom";
import 'babel-polyfill';
import {Provider} from 'react-redux';
import {configurestore} from './store/store';

const store = configurestore({})

    hydrate( 
        <Provider store={store}>
            <BrowserRouter> 
                <Template />
            </BrowserRouter>
        </Provider>
        , 
        document.getElementById("app")
    )

my Component.js

import React, { Component } from 'react';
import {connect} from 'react-redux';    
class Home extends Component {
      constructor(){
        super() 
      }

      render() {
        return (
          <div>
            <h1>Home</h1>
          </div>
        );
      }
    }

    const mapStateToProps = state =>{
      console.log(state,"<<<State in homepage")
      return state;
    }

    export default connect(mapStateToProps)(Home)

I am not getting how to set Aws data on the inital state which I define in action.js, my component always showing initial state which I define on index.js and I can't hold render function, how to Fix this.

Amit Shakya
  • 962
  • 3
  • 16
  • 30

1 Answers1

1

Try Loading Initial data before the app launch. You can load the initial data in app loading/Splash Screen and pass it to the Redux state as initial one. if your app is highly depended upon the data loading at startup, probably you should handle loading error in splash as well. Try loading minimal data on app startup otherwise it may highly effect you your app user experience. For more info on <AppLoading> Component, head over to react native expo documentation. expo has built in <AppLoading> component.

Vishal Vaghasiya
  • 1,857
  • 2
  • 14
  • 21
  • I have also tried to load data on server before app initialization but, with async way but problem is client is not showing the data which I binds to server. Client showing data which it have on index.js but I can't load AWS data on Clientside because I have aws credentials on dotEnv so it can be done on serverside only – Amit Shakya Jun 12 '19 at 16:42
  • I tried to load data for the initial state but what happening right now is, redux store showing data on server-side but clientside still showing blank data, Not getting how to set data for on store for clientside or send data from server store to client. – Amit Shakya Jun 13 '19 at 09:10