How to test top-level React component managing state? - javascript

So I have shallow render tests for all my Components that use just props. Some of them are Stateless functional like FB defines them, some of them are standard extended Components but without state.
Shallow is just great for these components. Very fast and I found a nice way to test that callbacks are passed properly as well without re-rendering.
Anyways - since I had to use rather big parent component that controls state and sets props for child (tested) components - now I have to test the parent component.
Note that this is part of legacy Rails app and currently I cannot use Redux. But I'm considering converting all parent component state manipulating methods (aka addTodo) to pure functions that will accept state as an argument etc.
What's the best practice to test this "parent" component:
Use shallow render again and just make sure that top-level methods (aka addTodo) are passed correctly to child components. Then test if the top-level methods return correct new state - they have to be pure because it seems I cannot access state when using shallow.
Use shallow render like in #1 but to test top-level methods use callback methods to actually call them, then rerender and test if the new "tree" contains new todo etc.
Resort back to DOM and Simulate for this component.
...
Thanks.

Related

Passing data up the components hierarchy in Modern React

In a react component hierarchy one can pass data from the root component to some component inside component tree by passing props. But what is the optimum way of passing data up the hierarchy? I can think of passing methods from the wrapper to the child. Is there any better way of handling data flow in a deep nested components scenario?
I don't think there is something wrong with passing callback functions from parent to child component.
But, in this case:
<parent onSomeEvent={..}>
<first-child onSomeEvent={..}>
<second-child onSomeEvent={..}>
...
When need to pass some data from child component to higher level parent, and you don't want to pass the callback function like above example you may use state management like react-redux, MobX. You can also use react context api and hooks if you don't want to use additional library.
You just have to keep in mind it isn't overkill for your app.

The difference between Vue-Test-Utils' "mount" and "shallowMount"?

Disclaimer: I am pretty new to Vue, JavaScript, and web frameworks in general.
I'm trying to familiarise myself with some basic unit and component tests using Jest and vue-test-utils.
I have read the docs on vue-test-utils' mount() and shallowMount()
, but I'm not sure when to use the one over the other (they appear to be very similar).
According to the docs on shallowMount():
Like mount, it creates a Wrapper that contains the mounted and
rendered Vue component, but with stubbed child components.
What exactly is meant by "stubbed child components"?
Can mount() and shallowMount() be used interchangeably?
What the documentation means by "stubbed child components" is that every components within the tested one will not be rendered. Instead, you will have a placeholder component.
This prevent your tests to be parasite by other component's behaviors.
In my opinion, you should always shallow mount your components when doing unit tests, and simply mount them when doing tests in your entire application.

What is the best approch to send data to its descendant in REACT

FOr example I have one parent component ( i'll call it animal)
and several child components (dog, cat, horse) and child's child components (Collie, English Foxhound, Fox Terrier, German Shepherd Dog). If i wanna send a function from animal to Collie, i have to send this function to Dog component and from Dog to Collie and only after 2 props i will be able to use this function in Collie component. Is there any better approch to send a function from animal directly to Collie ?
As mentioned by others on top the new Context API that was introduced in the new versions of react maybe different in react versions and still not recommended for just avoid passing props a fewer levels down in the component tree.
The component composition is a better option if you don't want to use redux which maybe complex for less usage like this example.
https://reactjs.org/docs/context.html#before-you-use-context
You basically create your parent component in this case <Animal/> to expected children nodes, <Dog />as well to expect children then you can later on pass it <Collie /> with the props.
Use the Context API.
Read more at the official docs : https://reactjs.org/docs/context.html
Basically, you define a context value and pass it with a Provider, which can be accessed by any node within the child tree.
Do note that the Context API is different for different versions of React and may change in future. You may also use Redux and react-redux for state management which would be internally using the context api.
You can use React Context API which is now official. More information as to how to use this can be found here - https://hackernoon.com/how-to-use-the-new-react-context-api-fce011e7d87
I would recommend to take a look at React "Component Composition" pattern (docs: https://reactjs.org/docs/composition-vs-inheritance.html). It is pretty straightforward and doesn't have a reusability issue that sometimes might occur in with React Context.
Ta-ta

Correct way to have a global variable in react

I'm developing a react.js project and before the main component is rendered, I call a function that returns an object that all components should be able to access. What is the correct way of doing this in react? Currently, I'm just passing it as a prop to the main component and then I suppose I should have to remember to pass it as a prop to all other components. Is there an easier or better way of doing this?
It seems like you are doing something like Redux. Passing the object as props should be okay. You could make a higher-order component that wraps your components and adds access to that global object via props. This is similar to Redux's connect.
As the expectation in React is application-wide concerns ,like a flux/redux/apollo store, are kept in a root provider component’s context and then accessed elsewhere in the component tree via a Higher Order Component or render props. This provides relief from globals and circular dependencies, and makes testing those components easier.
However, if you have non-component code that will need access to configuration values, you may need to use config global and writing components in a way that accepts config values from props.
see: https://github.com/lorenwest/node-config

what is a backing instance in react ?

Although the term backing instance is referred in react docs a lot, I couldn't get what it means. From react docs :
To interact with the browser, you'll need a reference to a DOM node.
You can attach a ref to any element, which allows you to reference the
backing instance of the component. This is useful if you need to
invoke imperative functions on the component, or want to access the
underlying DOM nodes.
link
This simplified component API is intended for components that are pure
functions of their props. These components must not retain internal
state, do not have backing instances, and do not have the component
lifecycle methods.
link
Because stateless functions don't have a backing instance, you can't
attach a ref to a stateless function component. Normally this isn't an
issue, since stateless functions do not provide an imperative API.
Without an imperative API, there isn't much you could do with an
instance anyway. However, if a user wants to find the DOM node of a
stateless function component, they must wrap the component in a
stateful component (eg. ES6 class component) and attach the ref to the
stateful wrapper component.
A backing instance is the object in memory which represents the node. This is where things like the state are usually stored.
So if you have a stateless component you won't have a backing instance because it is well stateless.
A few points regarding stateless components:
No lifecycle methods
No reference

Categories

Resources