cerebral-legacy / cerebral-module-router

An opinionated URL change handler for Cerebral
http://cerebral-website.herokuapp.com/documentation/cerebral-module-router
19 stars 4 forks source link

docs: example for component switcher #75

Open Guria opened 8 years ago

Guria commented 8 years ago
import Home from './components/Home';
import Admin from './components/Admin';

const pages = {Home, Admin};

@Cerebral({
  currentPage: 'app.currentPage'
})
class App extends React.Component {
  render() {
    const CurrentPage = pages[this.props.currentPage];
    return (
      <div>
        <CurrentPage/>
      </div>
    );
  }
}
// computed/getComponent.js
import Home from './components/Home';
import Admin from './components/Admin';
import NotFound from './components/NotFound';

const pages = {Home, Admin};

export default function getComponent (get) {
  let page = get('app.currentPage')
  if (page) {
    return pages[page]
  } else {
    return (props) => {
      return <NotFound page={page} ...props />
    }
  }
}

// component/App.js
import getComponent from '../computed/getComponent'
@Cerebral({
  Component: getComponent
})
class App extends React.Component {
  render() {
    const Component = this.props.Component;
    return (
      <div>
        <Component className="foo" />
      </div>
    );
  }
}
thesublimeobject commented 8 years ago

@Guria I really appreciate this example. The docs are a little bit spare, although that could just be because I am slightly new to a lot of this, but this example was very helpful. A few questions; this is how I have it set up for routing right now, and I have a feeling there is probably a slightly better way to go about it, but the docs aren't super clear on what actions to actually take once the signals are propagated, so I have kind of sewn together your example with the routing docs.

// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import Controller from 'cerebral'
import Model from 'cerebral-model-baobab'
import { Container } from 'cerebral-view-react'
import Router from 'cerebral-module-router'

// Modules
import DevTools from 'cerebral-module-devtools'
import UsersModule from './modules/Users'
import HomeModule from './modules/Home'
import AppModule from './modules/App'

// Components
import App from './App'

// Controller
const controller = Controller(Model({}))
controller.addModules({
    users: UsersModule(),
    devtools: DevTools(),
    home: HomeModule(),
    app: AppModule(),

    router: Router({
        '/': 'app.getHomeRoute',
        '/registration': 'app.getRegistrationRoute',
    }, {
        mapper: {query: true}
    })
})

// Render
ReactDOM.render(<Container controller={ controller } app={ App } />, document.getElementById('root'))
// ./modules/App.js (condensed)

// actions
function getHomeRouteAction({ state }) {
    state.set(['app', 'currentPage'], 'Home')
}

function getRegistrationRouteAction({ state }) {
    state.set(['app', 'currentPage'], 'UserRegistration')
}

// signals
const getHomeRoute = [getHomeRouteAction]
const getRegistrationRoute = [getRegistrationRouteAction]

// module
export default (options = {}) => {
    return (module, controller) => {
        module.addState({
            currentPage: 'Home',
        })

        module.addSignals({
            getHomeRoute,
            getRegistrationRoute,
        })
    }
}
// getComponent.js (per example)
import Home from '../components/Home'
import UserRegistration from '../components/UserRegistration'

const pages = { Home, UserRegistration }

export default function getComponent(get) {
    let page = get('app.currentPage')
    if (page) {
        return pages[page]
    }
}
// App.js
import React, { Component, PropTypes } from 'react'
import { Decorator as Cerebral, Link } from 'cerebral-view-react'
import UserRegistration from './UserRegistration'
import getComponent from './computed/getComponent'
import './styl/app.scss'

@Cerebral({
    // users: ['users', 'active'],
    Component: getComponent
})

class App extends Component {
    render() {
        const Component = this.props.Component
        return (
            <div>
                <Component />
            </div>
        )
    }
}

export default App

This actually does work well for me so far (not that long), but I am essentially wondering if I am going down the wrong path of something that happens to work. I guess, as I said before, I find the Cerebral docs a little confusing in the sense that I'm not sure what my actions should even be doing once I send a signal via the router. After seeing your example, it did make some sense, but I still feel a little unsure about it. Thanks so much for any help.

Guria commented 8 years ago

Your code looks pretty good. Seems you got it all right. Just a few notes:

function setCurrentPage (page)
  return function getHomeRouteAction({ state }) {
    state.set(['app', 'currentPage'], page)
  }
}

or just use cerebral-addons/set: set('state:/app.currentPage', 'Home')

It's pretty hard to support documentation. Please feel free to open issues into repositories to describe which part has poor documented.

thesublimeobject commented 8 years ago

Okay, great. This is helpful. As I get going I will open some issues if I see anything else that's really murky. I have really enjoyed using Cerebral so far in comparison to Redux. If I feel confident enough in my understanding I might even make some documentation suggestions as I tend to find that to be a tough thing for both users and maintainers in the current ecosystem. Thanks!

christianalfoni commented 8 years ago

@thesublimeobject Thanks for your feedback! We are working on a new webpage now. Details will be released after next hangout (thursday). Would love for you to join the hangout and/or get involved in building the new site :) https://plus.google.com/events/c86f24bbfhkaj4jhjb7tvjft2nc

thesublimeobject commented 8 years ago

@christianalfoni I'm not sure how confident I feel on contributions yet as I am still just using my free time to get a full understanding of best practices here, but I would love to join and help in any way that I can; been looking for ways to give back to the community. Count me in!

christianalfoni commented 8 years ago

Great stuff, are you on discord? Our channel/server is over here: https://discordapp.com/channels/133707918859173890/133707918859173890. There you will get latest news :)

Guria commented 8 years ago

@christianalfoni let's keep it open until included to docs