'How to ssr conditional component in nextJS?

I have been working with nextjs, react, and redux but I get stuck.

I want to ssr my conditional component. My code has 3 content component which will render if user clicks the link in the Navbar component based on the condition above. That code works exactly like I want, but when I view the source code in Chrome, none of the <Content /> components get rendered. Here is my code:

import React, { Component } from 'react';
import dynamic from 'next/dynamic';
import NProgress from 'nprogress';
import { connect } from 'react-redux';
import Router from 'next/router';
import {
  actionFinansial,
  actionKarierSukses,
  actionGayaHidup
} from '/actions/navbar/navbar';
import SearchBar from '/components/Navbar/SearchBar';

import Nav from '/components/Navbar/Nav';

const Content = dynamic(import('/components/Navbar/Content'));

Router.onRouteChangeStart = url => {
  console.log(`Loading: ${url}`);
  NProgress.start();
};
Router.onRouteChangeComplete = () => NProgress.done();
Router.onRouteChangeError = () => NProgress.done();

class Navbar extends Component {
  state = {
    isClick: false,
    active: ''
  };

  componentDidMount() {
    document.addEventListener('click', this.handleClickOutside);
  }

  componentWillUnmount() {
    document.addEventListener('click', this.handleClickOutside);
  }

  handleClickOutside = e => {
    if (this.nav && !this.nav.contains(e.target)) {
      this.resetNavbar();
    }
  };

  resetNavbar = () => {
    this.setState({
      isClick: false,
      active: ''
    });
  };

  handleClick = (e, data) => {
    e.preventDefault();
    const cond = data === e.target.className || data === e.target.id;

    if (cond) {
      this.setState({
        isClick: true,
        active: data
      });
    }
    if (data === this.state.active) {
      this.setState({
        isClick: false,
        active: ''
      });
    }
  };

  handleContent = id => {
    if (this.state.active === 'Gaya Hidup') {
      this.props.fetchGayaHidup(id);
    } else if (this.state.active === 'Finansial') {
      this.props.fetchFinansial(id);
    } else {
      this.props.fetchKarierSukses(id);
    }
  };

  renderArrow = (type, data) => {
    return <span id={type} className={data} onClick={this.handleClick} />;
  };

  render() {
    const karierSukses = {
      16: 'Karier',
      15: 'Sukses',
      10: 'Edukasi'
    };

    const gayahidup = {
      16: 'Hiburan',
      17: 'Jalan-Jalan',
      18: 'Tekno',
      19: 'Hobi',
      8: 'Hubungan',
      9: 'Pernikahan',
      14: 'Keluarga',
      12: 'Kesehatan',
      15: 'Rumah',
      11: 'Otomotif'
    };

    const finansial = { 16: 'Bisnis', 11: 'Keuangan', 12: 'Investasi' };

    const {
      imgBig,
      contentFinansial,
      contentKarierSukses,
      contentGayaHidup
    } = this.props;
    const { active, isClick } = this.state;

    return (
      <section className="navbar" ref={node => (this.nav = node)}>
        {/* Category Nav */}
        <Nav
          resetNavbar={this.resetNavbar}
          active={active}
          handleClick={this.handleClick}
          arrow={this.renderArrow}
        />

        {/* Category Content */}
        {this.state.active === 'Gaya Hidup' ? (
          <Content
            imgBig={imgBig}
            categoriesIds={gayahidup}
            handleContent={this.handleContent}
            active="8"
            activeName="Hubungan"
            content={contentGayaHidup}
          />
        ) : (
          ''
        )}
        {this.state.active === 'Finansial' ? (
          <Content
            imgBig={imgBig}
            icClick={isClick}
            categoriesIds={finansial}
            handleContent={this.handleContent}
            active="11"
            activeName="Keuangan"
            content={contentFinansial}
          />
        ) : (
          ''
        )}

        {this.state.active === 'Karier & Sukses' ? (
          <Content
            imgBig={imgBig}
            icClick={isClick}
            categoriesIds={karierSukses}
            handleContent={this.handleContent}
            active="10"
            activeName="Edukasi"
            content={contentKarierSukses}
          />
        ) : (
          ''
        )}

        {this.state.active === 'search-bar' ? <SearchBar /> : ''}

        <div className="navbar__search-icon">{/* <img src="" alt="" /> */}</div>
      </section>
    );
  }
}

function mapStateToProps(state) {
  return {
    contentFinansial: state.navbar.category.finansial,
    contentKarierSukses: state.navbar.category.karierSukses,
    contentGayaHidup: state.navbar.category.gayaHidup
  };
}

export default connect(mapStateToProps, {
  fetchGayaHidup: actionGayaHidup,
  fetchFinansial: actionFinansial,
  fetchKarierSukses: actionKarierSukses
})(Navbar);


Solution 1:[1]

Apparently contentGayaHidup (for instance), is passed as props, after you click the navbar, am I correct? There a quite a few things happening outside this code...

Could you try one of the following to see if that's the problem? If it is indeed the problem (the contentXXXXXX props updating but not passed to the render), you may have to find another way to pass them down; through the state (may be quite extensive though), through redux maybe...

Hati2 teman

1- Pass the props to the state

constructor(props){
  super(props);
  this.state={contentGayaHidup: this.props.contentGayaHidup}
}
// some more code
render() {
  return(
    {this.state.active === 'Gaya Hidup' ? (
          <Content
            imgBig={imgBig}
            categoriesIds={gayahidup}
            handleContent={this.handleContent}
            active="8"
            activeName="Hubungan"
            content={this.state.contentGayaHidup}
          />
        ) : (
          ''
        )}
  )
}

2- Use componentdidUpdate

componentDidUpdate(prevProps, prevState) {
        const {contentGayaHidup} = this.props;
        if(contentGayaHidup !== prevProps.contentGayaHidup){
            this.setState({contentGayaHidup: this.props.contentGayaHidup})
        }

    }

// some more code
render() {
  return(
    {this.state.active === 'Gaya Hidup' ? (
          <Content
            imgBig={imgBig}
            categoriesIds={gayahidup}
            handleContent={this.handleContent}
            active="8"
            activeName="Hubungan"
            content={this.state.contentGayaHidup}
          />
        ) : (
          ''
        )}
  )
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1