Testing React Component Strategy - javascript

What is the best way to test React's Components in Unit Tests?
The first problem is decorators (or HOCs). We don't want to test them, but without them it is really hard to mount deeply to test how it works as a components; but in order to make them work we have to mock all chain of Providers (which is ~3 components in our case, plus contexts, etc), and again, it is too fragile from my point of view.
Next question is about the logic inside components. I know, there are tons of articles with cool advice like "don't use logic inside your components", but we often need to maintain local state (like banners, etc). Should it be tested just with shallowMount, or it doesn't cost it too? Also lifecycle methods, if we start to check it, doesn't it make our tests too brittle and too much know about implementation?
And the last question is about the markup. Should we check anything inside the React Component? I read all sorts of tutorials, and I think that finding by tag is the worst example ever (I don't even want to go into details here). Jest snapshot feature for me doesn't seem a good choice too (I see absolutely the same problems here too). What I see could be helpful – just checking that different components are rendered when difference props are passed (like Loader and Offer, for instance, respectively), but sometimes they are children of some container itself, and shallowRendering doesn't work, which takes us back to the initial point.
To conclude, I see the point only in two things:
Testing logic for internal state (invoking methods and looking into new state)
Looking at rendering of components which render depending on props.
Second point can be really hard (because of deep nested children), so for now I am leaning towards rendering just a component (check that it didn't fail – in a shallow way), and checking logic by invoking methods and checking state after.
What are your strategies?

Related

What is "Tearing" in the context of the React-Redux?

Version 6.0 of React-Redux mentions:
In version 6, all components read the same current store state value from context, which means the tree will be consistent and not have "tearing".
I get that this is beneficial, but I'd like to understand the meaning of "tearing" in this context better, and I'd like to understand how the new approach they outline actually reduces "tearing," if anyone can elaborate.
I'm a Redux maintainer, and I wrote that paragraph.
This is specifically a concern that has been raised by Andrew Clark from the React team as a potential issue with external state management tools when used with React's upcoming "Concurrent Mode".
In Concurrent Mode, React will be able to pause a render pass through the tree, and resume calculating the rest of the tree later.
If the components in the tree are reading an external value, and that value were to change while React's rendering is paused, then some of the upper components in the tree might have rendered using external value 1, and some of the later components might have rendered using external value 2. That would result in inconsistent render output, because different parts of the tree determined their behavior based on differing values in the same render pass. This is "tearing".
Part of the idea behind using createContext for v6 was that since React ensures a given render pass uses the same context value everywhere, there would be no chance of tearing.
The v6 implementation does work, but it's not as efficient in some cases as we'd hoped. We're currently working on coming up with a different internal implementation that goes back to using direct subscriptions instead. This does potentially mean that tearing is a possibility again, but at this point we need to sit back and wait for the React team to finish putting Concurrent Mode together before we can spend time seeing what the issues really are.

ReactJS local vs global state and implementing redux at a later time

So we are about two months in on a project. This is the first time I have ever managed code writers and not written the code myself. I've been reading their code for the last week. What was suppose to be a simple React app has turned into a spaghetti mess.
I understand: redux helps to manage global state. But should that mean that all buttons should map to a global "action?" This has seemed to create this entire mess of objects scattered throughout the entire app. I keep asking myself, why are we using global state for everything when local state could be used for 90% of the application. This is the kind of code that gives me heartburn:
let subitems = SidebarItems[state.type].sub_items;
Store.dispatch(SidebarSubItemHandler(item.action, subitems[0], null));
if(item.sub_items[subitems[0]].param) {
browserHistory.push(`${item.sub_items[subitems[0]].path}/${item.sub_items[subitems[0]].param}`);
} else {
browserHistory.push(item.sub_items[subitems[0]].path);
}
subItembuttons = Object.keys(this.props.subitems.sub_items).map(subitem => {
let subItem = this.props.subitems.sub_items[subitem];
return <li className={this.props.activeSubItem.action == subItem.action ? "bottom-bar-item active" : "bottom-bar-item"}
onClick={e => this.props.onClickSubItem(e, subItem)}
key={subItem.action} style={this.props.subitems.inlineStyles.mobileSubItemLI}>
{subItem.item}
</li>;
});
The application is littered with all kinds of objects like these that map to "action" objects. So at this point we are making the decision to scrap the entire project and restart from scratch, but without redux. Let's try to do as much as possible using local state only. When it comes time, and we need global state for something, ONLY implement it for that something, not every single action in the app. Does this make sense?
So I guess my question is: If we develop an app using local state and just fundamental React, will we be creating un-reversable problems that would prevent us from implementing redux on a per item basis?
Quoting from the relevant Redux FAQ entry at http://redux.js.org/docs/faq/OrganizingState.html#organizing-state-only-redux-state:
Using local component state is fine. As a developer, it is your job to determine what kinds of state make up your application, and where each piece of state should live. Find a balance that works for you, and go with it.
Some common rules of thumb for determing what kind of data should be put into Redux:
Do other parts of the application care about this data?
Do you need to be able to create further derived data based on this original data?
Is the same data being used to drive multiple components?
Is there value to you in being able to restore this state to a given point in time (ie, time travel debugging)?
Do you want to cache the data (ie, use what's in state if it's already there instead of re-requesting it)?
Per your specific question: if you use the "container component" pattern fairly consistently, it should be relatively straightforward to swap those "plain React" containers for Redux-connected containers down the line. See https://github.com/markerikson/react-redux-links/blob/master/react-component-patterns.md#component-categories for articles on the "container/presentational component" pattern.
Two other thoughts. First, I recently co-authored an article that discusses why you might want to use Redux in a React application.
Second: yeah, that code looks kinda ugly. I'm hoping those are at least three different snippets from different parts of the codebase, rather than one snippet, but that's rather hard to read. The repeated use of "sub_items" and "subitems" seems like a bit of a red flag, readability-wise.
It also doesn't look like it's following good Redux practices. For example, idiomatic Redux code almost never references the store directly. Instead, references to dispatch and getState are available via middleware, and thus can be used in action creators via redux-thunk and redux-saga. Connected components can also access dispatch.
Overall: you are absolutely welcome to use as much or as little Redux as you want, and as much or as little local component state as you want. I think the larger issue, though, is how well your team actually understands Redux, and how they're trying to use it.

React + Redux performance optimization with componentShouldUpdate

I have a react/redux application which has become large enough to need some performance optimizations.
There are approx ~100 unique components which are updated via websocket events. When many events occur (say ~5/second) the browser starts to slow down significantly.
Most of the state is kept in a redux store as Immutable.js objects. The entire store is converted to a plain JS object and passed down as props through the component tree.
The problem is when one field updates, the entire tree updates and I believe this is where there is most room for improvement.
My question:
If the entire store is passed through all components, is there an intelligent way to prevent components updating, or do I need a custom shouldComponentUpdate method for each component, based on which props it (and its children) actually use?
You really don't want to do things that way. First, as I understand it, Immutable's toJS() is fairly expensive. If you're doing that for the entire state every time, that's not going to help.
Second, calling toJS() right away wastes almost the entire benefit of using Immutable.js types in the first place. You really would want to keep your data in Immutable-wrapped form down until your render functions, so that you get the benefit of the fast reference checks in shouldComponentUpdate.
Third, doing things entirely top-down generally causes a lot of unnecessary re-rendering. You can get around that if you stick shouldComponentUpdate on just about everything in your component tree, but that seems excessive.
The recommended pattern for Redux is to use connect() on multiple components, at various levels in your component tree, as appropriate. That will simplify the amount of work being done, on several levels.
You might want to read through some of the articles I've gathered on React and Redux Performance. In particular, the recent slideshow on "High Performance Redux" is excellent.
update:
I had a good debate with another Redux user a couple days before this question was asked, over in Reactiflux's #redux channel, on top-down vs multiple connections. I've copied that discussion and pasted it in a gist: top-down single connect vs multiple lower connects.
Also, yesterday there was an article posted that conveniently covers exactly this topic of overuse of Immutable.js's toJS() function: https://medium.com/#AlexFaunt/immutablejs-worth-the-price-66391b8742d4. Very well-written article.

ReactJS - How can a child find its parent?

Is there a way in ReactJS for a component to find out who it's parent is?
EDIT 1: Regardless of the merits of doing this, is there a way?
I haven't found a React way to do this - from what I can see, the idea is to pass callbacks down to the child from the parent, and the child calls the callback - unaware of the fact that the callback is actually on the parent.
I've tried setting an "owner" property, and that idea seems to work, but I wonder what's the best approach?
e.g.
<Parent>
<Child owner={this}/>
</Parent>
Then in the child component, I can do owner.method, and it seems to work fine. I know this isn't a true parent/child relationship, but is the closest I've found in my tests.
Some may say that callbacks are a cleaner way of doing this, but the parent/child relationship for some things (e.g. RadioButtonGroup and RadioButton) seems natural and would benefit from knowing this relationship, in my opinion.
EDIT 2: So it's not possible?
The thing that I don't like about the idea that it's not supported is
that HTML can be marked up with zero javascript - and it has implied,
default functionality - some elements are required to have parents -
they are defined as children of other elements (e.g. ul and li). This
can't happen in JSX because if there is interaction between the
elements - there has to be javascript events that bind the
components together - every single time you use them. Designers can't
simply write HTML like syntax - Someone has to step in and put some
javascript bindings in there - which then makes the maintenance
harder. I think the idea makes sense for overriding default behavior,
but default behaviors should be supported. And defaults would
require knowing either your parent, or who your owner is.
There are a number of benefits to not doing this, the main two are: reusability and encapsulation.
TL;DR you probably don't want to do this ever.
Let's say our RadioButton has this public interface:
<RadioButton active={true} onSelect={function(event){}}>text</RadioButton>
We could construct another component called SuperRadioButton, which might have a different way of presenting itself, but still have the same public api as RadioButton, so it's a valid child of RadioButtonGroup.
If we're accessing the parent, then the parent's internals become part of the public api of these components, and we need to be much more careful with how we change our code, because a change in any of these components could cause the entire application to break.
Callbacks. Owner properties. Passing events out to be caught by the root in the tree. Passing the root down through contexts.
There are ways, yes, but they're contrary to the conceptual model of react, which is to be explicitly top down at all times. The short version is "you can, but don't."
The fundamental problem is that you don't want a child mutating outside its parent's knowledge.
That means that the sole exception to this is the root of the component tree, so it's semi-legit to pass a member of that control downwards in props or contexts then to "pass things up" by telling the root, which may then repaint itself.
The application layer Flux does something not terribly dissimilar to this, but passes things outside of the component heirarchy entirely to a dataStore, which broadcasts things back in with events.

On using mixins in a CoffeeScript game engine

I am working on a CoffeeScript game engine for Html5 canvas. I came up with the "cool" idea to utilize mixins after I checked a very neat CoffeeScript implementation. I thought, it may be a very cool idea to reduce the various hierarchy of objects that game objects usually provide, by developing a set of mixin-based components, each of which has a very specific functionality. Then, when developing an actual game, one could build unique game objects on the fly by basically starting from one component and mixing it with a bunch of other components. This reduces the hierarchies and allows for frequent changes.
Then I thought about the possible collisions that might come up, for example having a few components define a method with the same signature. Now, I am not as excited as before.
What should I do? Is this a good way? I still like it, especially because of JS' underlying prototype mechanism, which allows for such an easy way to combine stuff on the fly.
You're talking about an entity component system. There are a couple written in JS; the most popular is Crafty, which is big but worth looking at. I recently wrote one in CoffeeScript (just for funsies; will probably never release it).
A few notes about collisions:
So first, the problem may be worse than you think: collisions will happen if two methods have the same name; JS doesn't differentiate function signatures. It also might not be so bad: why don't you just create a namespacing convention, where each behavior (meaning method) is named after the component it belongs to, like burnable_burn?
To take a step back though, mixins aren't the only way to build this - behaviors (i.e. things a component can do) don't have to be methods at all. The motivating question I ask is, how do you trigger a behavior? For example, you might do:
if entity.hasComponent "burnable" #hasComponent provided by your framework
entity.burn()
But that doesn't sound right to me; it creates a weird coupling between what's happening in your game and what components you have, and it's awkward to check if your entities implement the relevant component. Instead, I'd like behaviors to be listeners on events:
entity.send("applySeriousHeat") #triggers whatever behaviors are there
And then have your component do whatever it needs to do. So when you add a component to an entity, it registers listeners to events. Maybe it looks like (just sketching):
register: (entity) -> #called when you add a component to an entity
entity.listen "applySeriousHeat", -> #thing I do when this event is sent to me
#do burnination here
To bring that point home, if you do that, you don't care about collisions, because your behaviors don't have names. In fact, you want "collisions"; you want the ability to have more than one component respond to the same event. Maybe it burns and melts at the same time?
In practice, I used both setups together. I made entity.addComponent mix in the component's functions, since it's occasionally convenient to just call a behavior as a method. But mostly, the components declare listeners that call those methods, which helped with decoupling and reduced the awkwardness of having to use scoped names, since I don't call them directly in most cases.

Categories

Resources