user4108694
user4108694

Reputation:

can't route successfully between components in react app

I have a static react app (that means there is not server side rendering) located under example.com/web-class.gr. My problem is that I can't route between components when I use my sidebar menu.

For instance. When I navigate to example.com/web-class.gr/css-intermediate the page loads as expected. From now on if I navigate to different lessonName the page is loading as expected. But I also have exercises, which I can't load when I press the corresponding button in my menu. To get an idea this is my index.js file:

import React from 'react';
import { Link as ReactLink } from 'react-router';
import sidebarStore from './Sidebar/SidebarStore';
import lessonValues from '../../lessonValues';
import LessonStore from '../../LessonStore';
import SidebarLink from './Sidebar/SidebarLink';


export default class Sidebar extends React.Component {
  constructor() {
    super();
    this.state = {
      SidebarIsCollapse: sidebarStore.getCurrentState()
    }
    this.NavMdPlaceholderClass = 'hidden-xs col-sm-4 col-md-3 col-lg-3';
  }

  componentWillMount() {
    sidebarStore.on('change', () => {
      this.setState({ SidebarIsCollapse: sidebarStore.getCurrentState() });
      this.ChangeSidebarState();
    });
    this.RenderMainMenu();
  }

  ChangeSidebarState() {
    const NAV_DefaultClasses = "col-sm-4 col-md-3 col-lg-3 ";
    if (this.state.SidebarIsCollapse) {
      this.NavMdPlaceholderClass = NAV_DefaultClasses + "slideInLeft";
    } else {
      this.NavMdPlaceholderClass = NAV_DefaultClasses + "slideOffLeft";
    }
  }

  RenderMainMenu() {
    this.main_menu = [];
    for (let link of lessonValues) {
      let { Id, url, isExercise, title } = link;
      this.main_menu.push(<SidebarLink key={Id} url={url} isExercise={isExercise} title={title}/>);
    }
  }

  render() {
    return (
      <div class={this.NavMdPlaceholderClass} id="nav-md-placeholder">
        <nav id="sidebar">
          <ul id="main-menu">
            <li class="ripple-btn">
                <ReactLink to="/" onClick={this.SetLessonDetails.bind(this)}>
                  <span class="item-align-fix">
                    <i class="glyphicon glyphicon-home" style={{'marginRight': '10px'}}></i>
                    <strong>
                      <span>AΡΧΙΚΗ</span>
                    </strong>
                  </span>
                </ReactLink>
              </li>

              {this.main_menu}
          </ul>
        </nav>
      </div>
    );
  }
}

here is the SidebarLink component file:

import React from 'react';
import LessonStore from '../../../LessonStore';
import { Link as ReactLink } from 'react-router';

export default class SidebarLink extends React.Component {
  SetPageTitle() {
    LessonStore.setLesson(this.props.url);
  }

  render() {
    let glyphoconType = 'glyphicon ';
    glyphoconType += this.props.isExercise ? 'glyphicon-pencil' : 'glyphicon-ok-sign';
    glyphoconType += ' nav-ico untaken-lesson';

    return (
      <li class="ripple-btn">
        <ReactLink to={this.props.url} onClick={() => this.SetPageTitle()} >
          <span class="item-align-fix">
            <i class={glyphoconType}></i>
              <span>{this.props.title}</span>
          </span>
        </ReactLink>
      </li>
    );
  }
}

But if I refresh the page manually, I am able to reveal the exercise page. But now I can't navigate to any other element. Only if I click it in sidebar menu and manually refresh the page.

To sum up:

I use nginx and below is my rule for the project:

location ^~ /web-class.gr/ {
        try_files $uri $uri/ =404;
        if (!-e $request_filename){
            rewrite ^(.*)$ /web-class.gr/index.html break;
        }
    }

And lastly here is my sidebar component:

import React from 'react';
import { Link as ReactLink } from 'react-router';
import sidebarStore from './Sidebar/SidebarStore';
import lessonValues from '../../lessonValues';
import LessonStore from '../../LessonStore';
import SidebarLink from './Sidebar/SidebarLink';

// some other helper functions here

  render() {
    return (
      <div class={this.NavMdPlaceholderClass} id="nav-md-placeholder">
        <nav id="sidebar">
          <ul id="main-menu">
            <li class="ripple-btn">
                <ReactLink to="/web-class.gr/" onClick={this.SetLessonDetails.bind(this)}>
                  <span class="item-align-fix">
                    <i class="glyphicon glyphicon-home" style={{'marginRight': '10px'}}></i>
                    <strong>
                      <span>AΡΧΙΚΗ</span>
                    </strong>
                  </span>
                </ReactLink>
              </li>

              {this.main_menu}
          </ul>
        </nav>
      </div>
    );

Is there any problem with ReactLink to? On my apache machine all works as expected. I can't figure out why my program breaks.

Update

I provide the link of the site to help your job become easier. The site is in greek although I believe you can understand it's structure.

web-class.gr

Code on Github

Upvotes: 5

Views: 1492

Answers (2)

muyani
muyani

Reputation: 31

This One worked For me

NB

for React Router

use <BrowserRouter> tag only once to enclose the whole of your application.

Use this tag at the point of Rendering.

For Example

If you are using Create-React-app .Use this at your Index.js file

ReactDom.Render(<BrowserRouter><App/></BrowserRouter>)

Upvotes: 1

Dhruv Kumar Jha
Dhruv Kumar Jha

Reputation: 6567

Second Update:

Change your render code in react/index.js to

ReactDom.render(
  <Router history={browserHistory} >
    <Route path="/" component={Layout} >
      <IndexRoute component={Index} ></IndexRoute>
      <Route path="/exercise-1" name="exercise-1" component={Exercise1} ></Route>
      <Route path="/exercise-2" name="exercise-2" component={Exercise2} ></Route>
      <Route path="/exercise-3" name="exercise-3" component={Exercise3} ></Route>
      <Route path="/exercise-4" name="exercise-4" component={Exercise4} ></Route>
      <Route path="/exercise-5" name="exercise-5" component={Exercise5} ></Route>
      <Route path="/exercise-6" name="exercise-6" component={Exercise6} ></Route>
      <Route path="/:lessonName" name="lesson" component={Lesson} ></Route>
      <Route path=":lessonName" name="lesson" component={Lesson} ></Route>
    </Route>
  </Router>
,app);

i..e the path starts with /

Upvotes: 0

Related Questions