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

Bug? Always rendering Fragment with "/" route #153

Closed benmcmaster closed 7 years ago

benmcmaster commented 7 years ago

Home Fragment is always rendering on every route... if i have localhost:8080/about

I will see both About and Home Fragments rendering.

const routes = {
  '/work': {
    title: 'Work'
  },
  '/about': {
    title: 'About'
  },
  '/': {
    title: 'Home'
  }
}

and client/index.js:

const preloadedState = window.__PRELOADED_STATE__
delete window.__PRELOADED_STATE__

const {
  reducer,
  enhancer,
  middleware
} = routerForBrowser({
  routes
})

const store = createStore(
  combineReducers({ router: reducer }),
  preloadedState,
  compose(enhancer, applyMiddleware(middleware))
)

render(
  <Provider store={store}>
    <RouterProvider store={store}>
      <App />
    </RouterProvider>
  </Provider>,
  document.getElementById('root')
)

and client/app.js:

render () {
    return (
      <div>
        <hr />
        <Navigation />
        <hr />
        <Fragment forRoute='/about' >
          <About />
        </Fragment>
        <Fragment forRoute='/work' >
          <Work />
        </Fragment>
        <Fragment forRoute='/' >
          <Home />
        </Fragment>
      </div>
    )
  }

Am I missing something? Why would I get both home and another Fragment at the same time?

benmcmaster commented 7 years ago

I duplicated the problem on the Demo app

const Demo = ({ router }) => {
  return (
    <div className={styles.container}>
      <div>
        <h1 className={styles.tagline}>
          <span className={styles.secondary}>A Compendium of</span>
          <br />
          <span className={styles.primary}>Ipsums and GIFs</span>
        </h1>

        <div className={styles.nav}>
          <Link href='/'>Home</Link>
          <Link href={{ pathname: '/cheese', query: { is: 'cheese' } }}>
            Cheese
          </Link>
          <Link href='/dog'>Dog</Link>
          <Link href='/cat?is=cat'>Cat</Link>
          <Link href='/hipster'>Hipster</Link>
        </div>

        <div className={styles.panes}>
          <Fragment key='/' forRoute='/'>
            <div>
              <p>Home</p>
            </div>
          </Fragment>
          <Fragment key='/cheese' forRoute='/cheese'>
            <div>
              <p>Cheese</p>
            </div>
          </Fragment>
          <Fragment key='/dog' forRoute='/dog'>
            <div>
              <p>Dog</p>
            </div>
          </Fragment>
          <Fragment key='/cat' forRoute='/cat'>
            <div>
              <p>Cat</p>
            </div>
          </Fragment>
          <Fragment key='/hipster' forRoute='/hipster'>
            <div>
              <p>Hipster</p>
            </div>
          </Fragment>
        </div>
      </div>
    </div>
  );
};

From the documentation, it seems like this should work. It used to work in 12.1.2. I am using 13.1.0. What am I missing?

kkerr1 commented 7 years ago

@benmcmaster I am working on a solution for this. In the meantime you could accomplish this with some pretty simple logic.

where you want to render your home section:

{router.route === '/' 
  ? <div><p>Home</p></div>
  : null
}
nkpz commented 7 years ago

I wanted a syntax that would be easier to refactor later and this is what I've settled on:

<Fragment withConditions={() => this.props.router.route === '/'} forRoute="/">

Working well. The withConditions prop gets removed after this is fixed

benmcmaster commented 7 years ago

@kkerr1 @nnjpp I just tried out 13.1.2... I am still seeing this bug described above. Was this supposed to be fixed in 13.1.2?

benmcmaster commented 7 years ago

@kkerr1 @nnjpp actually sorry about that. It's working now. It seems like the package didn't upgrade and install properly... Not sure what happened there. Anyway, it's working as I would expect it to with this config:

  render () {
    return (
      <Fragment forRoute='/' className={styles.appRoot}>
        <div>
          <Navigation />
          <div>
            <Fragment key='/work' forRoute='/work'>
              <Work />
            </Fragment>
            <Fragment key='/about' forRoute='/about'>
              <About />
            </Fragment>
            <Fragment key='/' forRoute='/'>
              <Home />
            </Fragment>
          </div>
        </div>
      </Fragment>
    )
  }
tptee commented 7 years ago

Glad to hear this worked for you @benmcmaster !