-
-
Notifications
You must be signed in to change notification settings - Fork 155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Discuss about the state
pass into Link or navigate
#102
Comments
I've been thinking about adding a more generic prop called <Link to='/app' navigate={{ replace: true, state: { animated: true } }} />
// calls navigate({ replace: true, state: { .. }) This will, however, require us to change the interface of the navigate method to keep the backward compat, but we could of course process const navigate = (to, options = {}) => {
if (typeof options === 'boolean') options = { replace: options }
const { replace = false, state = null } = options
...
} But of course, that's a bit size-consuming. |
But the biggest question here is how are we going to return current const [match, params] = useRoute("/users/:id")
// when called with /users/1 and navigation performed with `history.state` = { animated: true }
// the result is:
match // true
params // { id: 1, animated: true } Which of course a bit hacky and conventional, but on the other hand will allow us to also merge query params later on. And it allow us to keep the semantics. I would rather have this than: const [match, params, state, query] = useRoute("/users/:id")
// looks complicated... Well, the last option is to leave it up to the user: const [match, params] = useRoute(...)
const state = history.state || {}
// params isn't polluted with the state in this case |
For scalability and compatibility, I should think of a way to replace |
Just my opinion, but in terms of the Link component from a usage perspective, I think I prefer @soulchainer’s idea of replace being a bool with an optional state object prop, e.g. <Link to="/" replace state={{ animate: true }} /> As for the hooks API the state and params would be seperate use cases no? So something like: // Matching path params
const [match, params] = useRoute("/users/:id")
// Get state
const [location, setLocation, state] = useLocation()
// With setLocation signature something like:
setLocation(to: String, replace: Bool = false, state?: Object) And then possibly just leave a search params hook in its own file, as it’s generally not going to be associated with "matching" a route, and it’s not really part of history API that import useSearchParams from 'wouter/search-params'
// Minimal implementation
const search = useSearchParams()
// With setSearch convenience method
const [search, setSearch] = useSearchParams() With Off the top of my head those seem like okay trade offs, and more closely match up with their respective browser APIs? Edits: Fleshed out some ideas/examples. |
|
The approach by @destructobeam in #102 (comment) sounds like a really good path forward. |
I think
|
@o-alexandrov Thanks, I absolutely agree with the point! I do think that the state support (as well as the search support) can be added through extensions. I already expressed my ideas in #108 (comment)
I was already able to implement most of the ideas here: #121 With the update above the state support could be as simple as following: import useLocationWithState from '@wouter/use-location-state';
const App = () => (
<Router hook={useLocationWithState}>
<Link to="/app" state={{ foo: 'bar' }}>Click Me</Link>
</Router>
); |
@o-alexandrov The suggestion wasn’t for wouter to manage state, but it already is an interface to the history API which itself has state, so the idea was to read/write to that. That said, a hook that would provide that seems like a good approach. |
i will try to make a pr for it |
@cbbfcd Ok!
|
@molefrog Thanks for your reply. 🆒 👇 import useLocation from '@wouter/location' so, the first features we need to implement in a beta version:
any supplement ? |
may be we can support hash router too. import useLocation from '@wouter/location'
// e.g. history default true, but if the browser does not support hash or set history false, we use hash router
useLocation({ history: true }) |
maybe an interceptor should be supported too in new const interceptor = (currentPath, nextPath) => {
if(confirm('Do you want to leave?')){
return nextPath;
}
return currentPath;
}
useLocation({ interceptor }) |
Should we maybe find a way to allow multiple "patching"? import { withState, withSearch } from '@wouter/addonds'
const useAdvancedLocation = withState(withSearch(useLocation)) |
Just curious if this is still planned. My project uses it with react-router and it's the only thing I haven't figured out how to convert to let us switch to wouter. Does anyone have a good pattern for a workaround? |
@tony-scio hi, 👋 ~ There is currently no best way to convince everyone. I think the simplest implementation is to pass the state through const navigate = useCallback(
(to, { replace = false, state = {} } = {}) =>
history[replace ? eventReplaceState : eventPushState](
{ state, key: createKey() },
"",
// handle nested routers and absolute paths
to[0] === "~" ? to.slice(1) : base + to
),
[base]
); and then mix it into the props in the Route component. // ...
const state = getStateFromHistory();
if (component) return h(component, { params, state });
// support render prop or plain children
return typeof children === "function" ? children({...params, ...state}) : children; as a workaround, you can control the |
There is no |
I've been busy lately, I'll try to provide an available |
Fyi, we added a full support for state navigation in v3.0.0 (see #346 and #349), you can now use v3.0.0-rc.1 to test it out. Usage: const [,navigate] = useLocation();
navigate("/", { state: "string" }) // state can be anything
navigate("/", { state: { foo: bar }})
<Link to="/" state={{ modal: true }} />
<Redirect to="/" state={{ modal: true }} /> Also, we have added a hook for hash navigation, and it does support state too: import { useHashLocation } from "wouter/use-hash-location"
<Router hook={useHashLocation}>
<Link to="/" state={{ modal: true }} />
</Router> |
Maybe we also need another way to pass parameters.
just like this:
@omgovich @molefrog
The text was updated successfully, but these errors were encountered: