5

I am trying to make a SSR react app, but not able to pass props from express to the component. What mistake am i doing?

server.js

import AppPage2 from './src/project02/LandingPage';
......
......
server.get('/project2',async (req,res)=>{
    const context = {data:'test'}
    const sheet = new ServerStyleSheet();
    const content = ReactDOMServer.renderToString(sheet.collectStyles(
        <StaticRouter location={req.url} context={context}>
            <AppPage2 state={{"foo":"baar"}}/>
        </StaticRouter>)
    );
    const styles = sheet.getStyleTags();
    let html = appShell( 'Project 2', content,' project2.bundle.js',styles)
    res.status(200).send(html);
    res.end()
})

AppPage2(./src/project02/LandingPage)

import React from 'react';
import {Wrapper,Title}  from './styleComponent/testStylePage'
.......
.......
class AppPage extends React.Component {

    componentDidMount() {
       console.log("{{API}}",this,this.props, this.props.staticContext)
    }

    render(){
        return(
            <Wrapper>
                <Title>This is project 01 </Title>
            </Wrapper>
        )
    }
}

export default AppPage;

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import AppPage from './project02/LandingPage'

ReactDOM.hydrate(
        <AppPage></AppPage>,
    document.querySelector('#root')
);

webpack.client.conf

const path = require('path');
const glob = require("glob");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;


const entry = glob.sync("src/*.js")
    .reduce((x, y) => Object.assign(x, 
        {
            [y.replace('src/','').replace('.js','')]: `./${y}`,
        }
), {});


    
    module.exports = {
            target: 'node',
            mode: 'development',//development,production
            entry: entry,
            output: {
                filename:'[name].bundle.js',
                path: path.resolve(__dirname,'build/public/'),
                publicPath: '/build/'
            },
            module: {
                rules: [
                    {
                        test: /\.js$/,
                        exclude: /(node_modules)/,
                        use: {
                            loader: 'babel-loader'
                        },
                        
                    },
                ]
            },
            plugins: [
                // new BundleAnalyzerPlugin()
            ]
        }

I am not able to log console.log("{{API}}",this,this.props, this.props.staticContext) from AppPage2(./src/project02/LandingPage) this page i am sending data from server.js(express)

ghost
  • 467
  • 2
  • 6
  • 19
  • 1
    componentDidMount called only on the browser. – Pulkit Aggarwal Jun 03 '21 at 06:32
  • You can set initialData on the window object by sending a script from the server which will execute on the browser and set initialData in the window object and use that data in componentDidMount. – Pulkit Aggarwal Jun 03 '21 at 06:43
  • By setting window object, my purpose of doing Server side rendering will go away. Using mobx/redux i am able to render on server . but i want to know how can we use it without mobx/redux – ghost Jun 03 '21 at 15:44
  • props will be available in render so you can use it in render and create your html and then send html to the browser. I was suggesting that if you want to use server data in componentDidMount then you have to set data in the window object. – Pulkit Aggarwal Jun 04 '21 at 03:38
  • state={{"foo":"baar"}} i am setting as props in express like this const content = ReactDOMServer.renderToString(sheet.collectStyles( ) ); but if i log props, its missing – ghost Jun 04 '21 at 08:50
  • As far as I know, we will not access data like this, we have to use the window object or cookie for small data if want to use it at the client-side. We can just use the above data on the server for creating the Html. – Pulkit Aggarwal Jun 04 '21 at 15:25

1 Answers1

1

Your props already passed to your component on Page2, but you're longing it using a function that will never been called,

componentDidMount() is invoked immediately after a component is mounted (inserted into the DOM tree).

in your case, you are not mounting any thing to the DOM, because react will only render your component to html and will not wait for your component to Mount, practically there is no DOM in your NodeJs server, and you're only rendering the component and return it as string, not inserting it to the DOM.

Your props are already there and you can console log them in your class constructor, and in your render method:

class AppPage extends React.Component {

    constructor (props){
        super(props)
        console.log("{{API}}",this,this.props, this.props.staticContext)
    }

    render(){
        //or console log it here
        console.log("{{API}}",this,this.props, this.props.staticContext)
        return(
            <Wrapper>
                <Title>This is project 01 </Title>
            </Wrapper>
        )
    }
}

in this state your compoenent will mount and not did mount you can also console log your props using UNSAFE_componentWillMount but as it's name said it's unsafe ReactJS.org

You can also create your own functions and it will works:

myFunction () {
   console.log(this.props.state)
}

myFunction();
butalin
  • 327
  • 3
  • 9