FormidableLabs / redux-little-router

A tiny router for Redux that lets the URL do the talking.
MIT License
1.04k stars 114 forks source link

Can't quite get this working... #185

Closed michaeljonathanblack closed 7 years ago

michaeljonathanblack commented 7 years ago

Hey @tptee

Sorry for all of the posts! I am trying to get this library integrated with our app, but not having the best luck.

I believe I have everything hooked up correctly, although there is likely something I'm overlooking as the behavior I am seeing is weird or broken. For reference, here is my root component, App.js:

import { Fragment } from 'redux-little-router';
import React from 'react';

import HeaderDemo from 'components/HeaderDemo';
import HomePage from 'modules/home/HomePage';
import AboutPage from 'modules/about/AboutPage';
import ManageAuthorPage from 'modules/authors/ManageAuthorPage';
import AuthorsPage from 'modules/authors/AuthorsPage';
import CoursesPage from 'modules/courses/CoursesPage';
import ManageCoursePage from 'modules/courses/ManageCoursePage';

class App extends React.Component {
  render() {
    return (
      <div className="container-fluid">
        <HeaderDemo />
        <Fragment forRoute="/"><HomePage /></Fragment>
        <Fragment forRoute="/about"><AboutPage /></Fragment>
        <Fragment forRoute="/author"><ManageAuthorPage /></Fragment>
        <Fragment forRoute="/author/:id"><ManageAuthorPage /></Fragment>
        <Fragment forRoute="/authors"><AuthorsPage /></Fragment>
        <Fragment forRoute="/courses"><CoursesPage /></Fragment>
        <Fragment forRoute="/course"><ManageCoursePage /></Fragment>
        <Fragment forRoute="/course/:id"><ManageCoursePage /></Fragment>
      </div>
    );
  }
}

export default App;

And here is what I am seeing:

  1. Visiting / loads correctly, the homepage is shown, and there are no errors in the console.
  2. Clicking on a link to /about sort of works. The contents of the AboutPage component load below the HomePage component. For some reason, HomePage is not unloaded.
  3. Clicking on a link to /courses does the same thing as with the AboutPage, but throws an error in the console for connectAdvanced.js?a26c:241
    Uncaught TypeError: Cannot read property 'id' of undefined at Function.mapStateToProps [as mapToProps] (eval at <anonymous> (bundle.js:3444), <anonymous>:79:33) ...
  4. Reordering my Fragments affects the output, e.g. putting /course before /courses does bad stuff. I assume I'm supposed to nest these co-matching routes in some way?

--OH WAIT!

Okay, I figured out the route nesting after some trial and error. I wish the documentation around creating a series of Fragments was clearer, maybe I'll add a PR to clear that up. Here is what I landed on:

import { Fragment } from 'redux-little-router';
import { PropTypes } from 'prop-types';
import React from 'react';

import HeaderDemo from 'components/HeaderDemo';
import HomePage from 'modules/home/HomePage';
import AboutPage from 'modules/about/AboutPage';
import ManageAuthorPage from 'modules/authors/ManageAuthorPage';
import AuthorsPage from 'modules/authors/AuthorsPage';
import CoursesPage from 'modules/courses/CoursesPage';
import ManageCoursePage from 'modules/courses/ManageCoursePage';

class App extends React.Component {
  render() {
    return (
      <div className="container-fluid">
        <HeaderDemo />
        <Fragment forRoute="/">
          <div>
            <Fragment forRoute="/"><HomePage /></Fragment>
            <Fragment forRoute="/about"><AboutPage /></Fragment>
            <Fragment forRoute="/authors"><AuthorsPage /></Fragment>
            <Fragment forRoute="/author">
              <div>
                <Fragment forRoute="/"><ManageAuthorPage /></Fragment>
                <Fragment forRoute="/:id">
                  <ManageAuthorPage />
                </Fragment>
              </div>
            </Fragment>
            <Fragment forRoute="/courses"><CoursesPage /></Fragment>
            <Fragment forRoute="/course">
              <div>
                <Fragment forRoute="/"><ManageCoursePage /></Fragment>
                <Fragment forRoute="/:id">
                  <ManageCoursePage />
                </Fragment>
              </div>
            </Fragment>
          </div>
        </Fragment>
      </div>
    );
  }
}

App.propTypes = {
  router: PropTypes.object,
};

export default App;

I only have one glaring issue right now, and one lesser issue that is likely just a bug in this framework or a product of how Redux DevTools handles things.

  1. push doesn't seem to do anything. I don't see an action in the RDT Inspector and the browser doesn't go anywhere. Do I need to mapDispatchToProps in some way? Here's the relevant code from my Course component:
  saveCourseSuccess() {
    toastr.success('Course saved');
    push('/courses');
  }

  saveCourse(course) {
    return this.props.actions
      .saveCourse(course)
      .then(() => {
        this.saveCourseSuccess();
      })
      .catch(error => {
        throw new SubmissionError({ _error: error });
      });
  }
  1. Time travel in Redux DevTools doesn't work through routes. If I go backward past when a route was rendered, the previous route does not render. I'm not sure if it's supposed to... but it doesn't.
  1. This is likely a webpack issue, but I want to delineate it here: The error I saw above regarding mapStateToProps was pretty straightforward, it was params missing from ownProps.params.id from my previous, React Router-based implementation. Why the error didn't point at the file and the line number, instead of anonymous and bundle.js is something I need to figure out. Source mapping should be there.

Mostly though I'm concerned about #1, if you can give me any insight! And sorry for the long post, it was largely a tool for me to work through my implementation, haha. Hopefully I'll get this all up and running and then I can get some PRs together for you that improve documentation for people like me 💃

Best Michael

baebb commented 7 years ago

@mherodev for 1. Have you tried wrapping that push in a redux-thunk dispatch?

eg.


export function navigateAbout() {
  return (dispatch) => {
    dispatch(push('/about'))
  }
}
michaeljonathanblack commented 7 years ago

Blergh, of course! Sorry, it's been a minute since I've used Redux, just getting back into the swing of things. Thanks Ross.

I'm going to leave this issue open for now as a task for me to update documentation to reflect the smaller stuff like this for green Redux developers like myself.

baebb commented 7 years ago

Happy to help 👍

michaeljonathanblack commented 7 years ago

Yay, things were merged! Thanks again for the help and for the library 💃

tptee commented 7 years ago

Of course! Thanks for your patience 😄