Skip to content
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

Inject resolves as individual props #55

Closed
elboman opened this issue Jun 7, 2017 · 1 comment
Closed

Inject resolves as individual props #55

elboman opened this issue Jun 7, 2017 · 1 comment

Comments

@elboman
Copy link
Member

elboman commented Jun 7, 2017

Hello everyone,

We have been discussing whether to change the current UIView behaviour regarding the injected resolves in the routed component.

Problem:

Currently the UIView component wraps all the resolves into a single resolves prop that is injected in the routed component. This makes the routed component coupled to the router API, which renders it non reusable in other situations.

// state declaration
const myState = {
  url: '/',
  name: 'myState',
  component: MyComponent,
  resolve: [
    { token: 'someResolve', resolveFn: () => MyService.getSomeData() }
  ]
}

// class component
class MyComponent extends Component {
  render() {
    const {someResolve} = this.props.resolves;
    return (
      <p>Resolved is: {someResolve}</p>
    );
  }
}

// or function component
const MyComponent = ({ resolves }) =>
  <p>Resolved is: {resolves.someResolve}</p>;

Solution:

We were thinking about injecting the resolves as individual props, in order to decouple the component from the router API, especially when the component doesn't access the transition so it doesn't really need to know about the router at all.

// class component
class MyComponent extends Component {
  render() {
    const {someResolve} = this.props;
    return (
      <p>Resolved is: {someResolve}</p>
    );
  }
}

// or function component
const MyComponent = ({ someResolve }) =>
  <p>Resolved is: {someResolve}</p>;

Thoughts:

The change in code would be trivial, but this would be a breaking change as every routed component must be updated accordingly (nothing too painful, but still a pita).

The other problem we see with this solution is the risk of props collision, especially with the transition props that is silently injected along with the resolves. This means the user has some restriction on what names can be used for the resolves, and it might be wise to add a warning in case of collision.

Ultimately we wanted to know what y'all think about this change, if you have incurred in any problem related to this and if you think you would benefit from this update. Please keep in mind that the current version is a pre-release and this would be the best time to implement such a breaking change, before hitting production-ready stable versions.

@Kukkimonsuta
Copy link
Contributor

What if we removed the transition prop and force user to resolve it? This way there would be no possible conflicts, no magic and maybe we could even register other resolvables (for instance I usually need StateService and not Transition, so i could just pull that from DI).

interface ReportsProps {
	router: UIRouterReact;
}

class Reports extends React.Component<ReportsProps, void> {

	handleGoHomeClick = () => {
		const { router } = this.props;

		router.stateService.go('home');
	}

	render() {
		return <div>Reports! <button onClick={this.handleGoHomeClick}>Go home</button></div>;
	}
}

const ReportsState = {
	name: 'reports',
	url: '/reports',
	resolve: [
		{ token: 'router', resolveFn: (transition: Transition) => transition.router, deps: [Transition] },
	],
	component: Reports
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants