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

What are good ways to keep logic/side effects separated from the views/components in React? #664

Closed
Yakimych opened this issue Apr 16, 2019 · 9 comments

Comments

Projects
None yet
2 participants
@Yakimych
Copy link

commented Apr 16, 2019

Hi Kent!

I was wondering if you have any recommendations for structuring/architecting React applications. More specifically I am interested about separation of concerns - keeping side effects and logic separate from views/components. The topic interests me, since React itself is not really opinionated with regard to this, and this is an issue that's always getting out of hand as applications grow in size.

Thanks!

@kentcdodds

This comment has been minimized.

Copy link
Owner

commented Apr 16, 2019

Great question! Here's your audio answer: 3 Minutes with Kent #105

@kentcdodds kentcdodds closed this Apr 16, 2019

@Yakimych

This comment has been minimized.

Copy link
Author

commented Apr 16, 2019

Nice, thanks! If I were to sum up, you recommend to keep the views and logic as close together as possible for as long as possible, at least as long as you don't start feeling some pains.

The thing is, I start feeling lots of pain because stuff gets really messy really really quickly - I would say roughly around the 8-10 component threshold, which is the reason for the question :)

But I guess I am doing something wrong - thanks a lot for taking the time to respond, it's really appreciated!

@kentcdodds

This comment has been minimized.

Copy link
Owner

commented Apr 16, 2019

Yeah, this follows the idea of AHA Programming: https://kcd.im/aha

You mean like 8-10 components in the whole app? Or like, in a single file?

@Yakimych

This comment has been minimized.

Copy link
Author

commented Apr 16, 2019

Yeah, I've read this one, good stuff!

Yep, the whole app. I start getting lost as to which component does what, how they communicate with each other. Making sure local state gets updated whenever the component receives new props is probably the biggest pain, and if this has to happen several levels deep into the tree, I usually just quit :)

State containers kind of solved this problem for me, but I am wondering how people manage to keep things structured while using pure React.

@kentcdodds

This comment has been minimized.

Copy link
Owner

commented Apr 16, 2019

Making sure local state gets updated whenever the component receives new props is probably the biggest pain

Worrying about keeping your local state in sync with props is definitely the problem there. There should only be one source of truth: props or state. Not both.

@Yakimych

This comment has been minimized.

Copy link
Author

commented Apr 16, 2019

Exactly! Coincidentally it's a date picker component (just as in the example you provide in the audio answer) I had trouble with. We were developing one with local state that kept track of days, months, years, whether the calendar was open or not - that sort of stuff. All was well until we had to change the date from outside of the component (like a button somewhere else that pushed a new date into it). Suddenly we need getDerivedStateFromProps and trying to figure out whether to compare props to state or to old props. Things got even worse when the application evolved to two datepickers for a date range, and we were trying to have interdependent validation in the parent component (one should always be earlier than the other).

Maybe it's simpler with useEffect now and one can avoid lifecycle methods, but this was an example when it became unmanageable with 4 components (Root, DateRange, 2 date pickers).

@kentcdodds

This comment has been minimized.

Copy link
Owner

commented Apr 16, 2019

Ah, that's when you need control props! I teach about control props in https://kcd.im/advanced-react

I've updated the material for hooks and I'll be giving a remote workshop about it in a few weeks! Stay tuned on https://kcd.im/news to be informed when tickets for that workshop go on sale :)

@Yakimych

This comment has been minimized.

Copy link
Author

commented Apr 16, 2019

Wow, I've never seen this - looks like a nifty pattern to have in the toolbelt (looking at the codesandbox example): on: this.isControlled('on') ? this.props.on : this.state.on.

I didn't know this was possible to achieve without relying on lifecycle methods/useEffect hook.

To be really nitpicky, one could argue that this goes somewhat against your previous "one source of truth: props or state" advice, but I guess there is a reason it's in the "Advanced React" section :)

Thanks again for taking the time to answer!

@kentcdodds

This comment has been minimized.

Copy link
Owner

commented Apr 16, 2019

It's all about the "one source of truth" for the lifetime of the component. This is why you get the "uncontrolled changed to controlled" warning with <input /> elements when you set the value prop late. Those implement control props! :) So the element supports both the controlled and uncontrolled form, and you as the user are responsible for using it either as controlled or uncontrolled, but never both during the lifetime of an instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.