-
Notifications
You must be signed in to change notification settings - Fork 130
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
connectWithRouter #54
Comments
Why do you feel you would need to access the context? Do you need the router instance? Because you can always bootstrap the router manually and pass the instance to the |
I can use the instance passed from The above HOC is really to act somewhat like dependency injection. My components can remain unaware of Including |
I think I understand what you're saying. Maybe a better question is: is there something specific you need to access the router instance for that isn't provided by the existing state/view management APIs? Thanks. |
I think it is necessary, too. I implemented it in my project but it's better to find it in the main package. |
Okay, can you guys please explain some use cases so we can understand how best to approach the problem? Thanks. |
So let's imagine that you have some nested components and your root component is connected to router via |
Several months later and I think I am becoming proficient with TypeScript. :-) I have an updated import {UIRouterReact} from '@uirouter/react';
import PropTypes from 'prop-types';
import React, {
Component,
ComponentType
} from 'react';
// Diff / Omit taken from:
// https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-311923766
// Native `Exclude` can replace `Diff` in `typescript@^2.8.0`
export type Diff<T extends string, U extends string> =
({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T];
export type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;
export const defaultUpdate = (router: UIRouterReact, forceUpdate: () => void) => (
router.transitionService.onSuccess({},() => (forceUpdate()))
);
export default <TRouterProps, TNeedsProps extends {}>(
params: (
router?: UIRouterReact,
ownProps?: TNeedsProps
) => TRouterProps = (
router: UIRouterReact,
ownProps
) => ({
...ownProps as {},
router
} as any),
update: false | typeof defaultUpdate = defaultUpdate
) => (
<P extends TRouterProps, C extends {router: UIRouterReact}>(
WrappedComponent: ComponentType<P>
) => (
class Connector extends Component<
Omit<P, keyof TRouterProps> & TNeedsProps,
Omit<P, keyof TRouterProps> & TNeedsProps
> {
public static contextTypes = {
router: PropTypes.object
};
public constructor(props: P & TNeedsProps, context: C) {
super(props, context);
this.context = context;
this.state = params(this.context.router, this.props as any) as any;
if (update) {
update(this.context.router, () => {
this.setState(params(this.context.router, this.props as any));
return this.forceUpdate();
});
}
}
public render() {
return (
<WrappedComponent
{...this.state}
{...this.props}
/>
);
}
}
)
); In addition to the params function accepting Also, I ran into an issue where I would need the component to receive the latest values from the Soon I will be exporting EDIT: HOC now caches props in state for more fine tuned control of updates. |
@schlesiger You may want to fix your readme. It says |
Whoops that's embarrassing. I'll update it along with these changes. Thanks! |
Yeah, I was thinking that with the new context API we should get the |
feat(UIRouterConsumer): add new `<UIRouterConsumer>` component to access the router instance via the new context API. example: ```jsx import {UIRouterConsumer} from '@uirouter/react'; class SomeComponent extends React.Component { render () { const router = this.props.router; // use the router via props return <div>whatever</div> } } export default () => <UIRouterConsumer> {router => <SomeComponent router={router} />} </UIRouterConsumer> ``` BREAKING CHANGE: `@uirouter/react` now uses the new React 16.3 Context API. If you were accessing the router instance via the legacy context api (which was never explecitly supported) you need to update your code accordingly: before: ```jsx class SomeComponent extends React.Component { static contextTypes = { router: PropTypes.object } render () { // access context via this.context const router = this.context.router; // do whatever needed with the router } } ``` after: ```jsx class SomeComponent extends React.Component { render () { // access router via props const router = this.props.router; // do whatever needed with the router } } // when rendering the component wrap it with the `<UIRouterConsumer>` component <UIRouterConsumer> {router => <SomeComponent router={router} />} </UIRouterConsumer> ``` Closes #54
feat(UIRouterConsumer): add new `<UIRouterConsumer>` component to access the router instance via the new context API. example: ```jsx import {UIRouterConsumer} from '@uirouter/react'; class SomeComponent extends React.Component { render () { const router = this.props.router; // use the router via props return <div>whatever</div> } } export default () => <UIRouterConsumer> {router => <SomeComponent router={router} />} </UIRouterConsumer> ``` BREAKING CHANGE: `@uirouter/react` now uses the new React 16.3 Context API. If you were accessing the router instance via the legacy context api (which was never explecitly supported) you need to update your code accordingly: before: ```jsx class SomeComponent extends React.Component { static contextTypes = { router: PropTypes.object } render () { // access context via this.context const router = this.context.router; // do whatever needed with the router } } ``` after: ```jsx class SomeComponent extends React.Component { render () { // access router via props const router = this.props.router; // do whatever needed with the router } } // when rendering the component wrap it with the `<UIRouterConsumer>` component <UIRouterConsumer> {router => <SomeComponent router={router} />} </UIRouterConsumer> ``` Closes #54
I suggest a connect component for ui-router-react be provided since accessing context directly isn't ideal. Something like:
Sorry I'd make a PR but I am not familiar enough with TypeScript.
The text was updated successfully, but these errors were encountered: