anthonyshort / deku

Render interfaces using pure functions and virtual DOM
https://github.com/anthonyshort/deku/tree/master/docs
3.41k stars 130 forks source link

A hard problem in the absence of context #404

Open ashaffer opened 8 years ago

ashaffer commented 8 years ago

Since there's been some talk of removing context, here's a problem that we may want to solve first:

<a href="/some-page" />Some Page</a>

How do you style links to the current page differently than others? Links are something that exist inherently at the leaves of your tree, so a solution that involves passing the current url down seems somewhat impractical. You also may have arbitrarily complex pattern matching to determine when a link is considered active that is coupled to the routing solution you use at the top.

Anyone got any clever solutions to this problem?

@anthonyshort @rstacruz @troch

rstacruz commented 8 years ago

yeah, without context that'd have to be done through <NavBar active='/some-page' />.

thebearingedge commented 8 years ago

I'm curious about this too. I started thinking about a <Link/> component for my router, but without context I can only think to:

import { Link } from 'my-router'

const ListOfLinks = ({ props }) => {
  const { entities, location } = props
  return (
    <ul>
      { entities.map(entity =>
        <li>
          <Link to={`/entities/${entity.id}`} from={location} activeClass={'is-active'}/>
            { entity.name }
          </Link>
        </li>
      ) }
    </ul>
  )
}

Something has to be passed down starting at least at top-level components assigned to <Route/>s. Maybe pass a location object that <Link/> uses to compute isActive or pass Link itself as a prop that internally references the Router...

thebearingedge commented 8 years ago

... or at least was dynamically created by the router before being added to props

anthonyshort commented 8 years ago

Yeah we need to figure out a solution for it. I might just wrap all of these issues up into a single thread and summarise everything up until this point. I'm still thinking it could be best to just pass a context object down like you would any other prop. It'd probably be easier to follow. Then we solve for the UX problem in v3.

Thoughts?

ashaffer commented 8 years ago

I've created a primitive that I think essentially solves this problem: redux-subscribe. This let's you create context components that store values from the global state atom in their own local state.

This does require you to have a primitive for doing local state, but that is a bit easier to achieve than the general context problem.

troch commented 8 years ago

A bit late to the conversation. I didn't know there were talks about removing context.

For links, with my implementation of routing I need to have access to the router instance for it to tell me if a link is active or not. Because a router instance might not be stateless (if you don't treat the URL of the page as your source of truth), having it in context prevents the use of singletons and therefore keep things server-side friendly.