1

I'm trying to implement react-router in my project and experiencing huge concept misunderstanding . For some of components in my app I need to fetch data from server. Previously I did it with this code:

$.get('/getSmData', options, function (result) {
      // set state with result or whatever
      }.bind(this));

placed in componentDidMount or in onClick functions but now, in order to make server routing, all requests go to my routing file.

How do I fetch data?

This is routing part of my server:

var  renderToString = require( 'react-dom/server').renderToString
var  match = require('react-router').match
var RouterContext  = require('react-router').RouterContext
var routes = require('./routes')

app.get('*', function (req, res) {

  match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
    if (error) {
      res.status(500).send(error.message)
    } else if (redirectLocation) {
      res.redirect(302, redirectLocation.pathname + redirectLocation.search)
    } else if (renderProps) {
        res.render('index', {
          react: renderToString(React.createElement(RouterContext, renderProps)),
          })
    } else {
      res.status(404).send('Not found')
    }
  })
})

This is routes.js

module.exports=  (
<Router history={browserHistory}>
      <Route path='/' component={index.App}>
          <Route path='/firstPage' component={First}>
            <Route path=':firstPageChild' component={FirstCh}/>
          </Route>
          </Route>
          <Route path='/secondPage' component={Second}/>
        </Route>
  </Router>

);

And let's say I need to fetch some data in child of one of children of firstPageChild in onButtonClick function. I can't prerender data and send with markup, so how should I do that?

2 Answers 2

2

I believe you have found the answer. But please let me answer, in case someone has the same problem (like I did, this morning).

  1. You should move the 404 error handling out of your "match react router" function,
  2. Add the third parameter "next" to the return function #1 above,
  3. Place your code to return AJAX data below this function.
  4. Create a route to handle the 404 not found error and place it on bottom.

So your code will be like this:

    app.get('*', function (req, res, next) {
       match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
          if (error) {
              res.status(500).send(error.message)
          } else if (redirectLocation) {
              res.redirect(302, redirectLocation.pathname + redirectLocation.search)
          } else if (renderProps) {
              res.render('index', {react: renderToString(React.createElement(RouterContext, renderProps)),
              })
          } else {
              // release control to the next middleware, in this case your URL for catching AJAX data
              next();
          }
       })
    })

    // return your AJAX data 
    app.get('/getSmData', function (req, res) {            
       res.send({ status: 'ok' });
    });

    // return 404 not found error 
    app.use(function (req, res) {            
       res.status(404).send('Not found');
    });
Sign up to request clarification or add additional context in comments.

1 Comment

That's also very nice solution!
0

It seems i've figured it out. Apparently if app.get('*') stands after other requests it gonna catch only others and it totally makes sense.

1 Comment

In case you don't know, you can also accept your own answer if it solved your problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.