Best practice to catch last render in React Component - reactjs

I have a question regarding a situation I am currently having. While I have found a workaround, I don't think it's the best practice. First thing my component does is make an API get call and send the results to the this.props. Following that I have a conditional check based on those props. Here's the problem, the component renders multiple times (4), and the prop being called is a prop from a previous state. So I have to wait for the second render before continuing. Here is a layout of my workaround.
import React from 'react'
class TestComponent extends React.Component{
componentDidMount(){
api = this.make.apiCall()
}
render(){
let something = null
console.log('Render Test Comp')
if(this.props){
something = (
<div>this.props Exsists</div>
)
}
return(
<React.Fragment>
{something}
</React.Fragment>
)
}
}
export default TestComponent
So basically what I want to know is, was the best possible method to catch the LAST render of a page? Is my method above ok? Is there a better way? Should I throw the conditional statement inline the JSX(which I think is so ugly and confusing if you have nested conditional statements inside your JSX)? You guys all rock, and have always answered my questions that are much more specific. This one should be easy ;)

I cannot answer your question here, because the code is wrong in many ways. Plus your code snippet does not make sense with the explanation.
Problem 1:
api = this.make.apiCall()
Where is this.make.apiCal()? What response is expected?
api should be a state from what I see. In order to rerender your component because of change got from api call.
Problem 2:
if(this.props){
something = (
<div>this.props Exsists</div>
)
}
This is absolutely wrong because this case will always be triggered. this.props is {} i.e. empty object which is truthy value.
See the Pen
Hello World in React by Tulsi Sapkota (#tolsee)
on CodePen.

Related

How to test react components props (expect component to be called with)

I need to test that a react component is called with opened={true} prop after an button click is fired. I am using testing-library ( testing-library/react + testing-library/jest-dom).
I mocked the Component using something like
import Component from "./path-to-file/component-name"
...
jest.mock("./path-to-file/component-name", () => {
return jest.fn().mockImplementation(() => {
return null
})
})
I first tried with:
expect(Component).toBeCalledWith(expect.objectContaining({"opened": true}))
expect(Component).toHaveBeenCalledWith(expect.objectContaining({"opened": true}))
expect(Component).toHaveBeenLastCalledWith(expect.objectContaining({"opened": true}))
but I got Error: expect(jest.fn()).toBeCalledWith(...expected).
Same went for expect.objectContaining({"opened": expect.anything()})
And even for expect(Component).toBeCalledWith(expect.anything())
And the difference is empty array:
I also tried with expect(ChartMenu.mock).toBeCalledWith(expect.anything()). I got a different error but still not working (this time the error was Error: expect(received).toBeCalledWith(...expected) + Matcher error: received value must be a mock or spy function)
Thank you in advice!
EDIT: here is a simplified version of the component I want to test:
const Component = () => {
const [chartMenuOpened, setChartMenuOpened] = useState(false)
return (
<Flex>
<EllipseIcon onClick={() => setChartMenuOpened(true)}>
+
</EllipseIcon>
<ChartMenu
opened={chartMenuOpened}
close={() => setChartMenuOpened(false)}
/>
</Flex>
)
}
Basically I want to make sure that when the + icon is clicked the menu will be opened (or called with open value). The issue is that I cannot render ChartMenu because it needs multiple props and redux state.
I was able in the end to mock useState in order to check that the setState was properly called from the icon component (in order to make sure there won't be future changes on the component that will break this using this post).
But I would still really appreciate an answer to the question: if there is any way to create a spy or something similar on a react component and check the props it was called with? Mostly because this was a rather simple example and I only have one state. But this might not always be the case. Or any good idea on how to properly test this kind if interaction would be really appeciated.
I think you are on the right track to test if the component has been called with that prop, it's probably the syntax issue in your code
I learn this trick from colleague and you can try to see if this helps fix your issue.
expect(Component).toHaveBeenCalledWith(
expect.objectContaining({
opened: true,
}),
expect.anything()
);
While the question on how to is answered, I did some extra research on this and it seems like in React components there is a second parameter refOrContext (so basically most of the time it's an empty object, but it can also be a ref or a context)
Despite pointing out the reason for the behavior, I also wanted to highlight that it is safer to use expect.anything() as the second argument (rather than just {} which would work only in most of the cases ):
More information about React second argument here

React-native ComponentDidMount not firing

i tried to update the sound array which i imported from other component every time it is changed. But however, it only fire componentDidMount() only once and it won't run again. Down below is my code on the problem:
//sound array from another component
import { soundArray } from "./CreateRecord";
export default class RecordingList extends React.Component {
constructor() {
super();
this.currentSoundArray = [];
}
componentDidMount() {
console.log(this.currentSoundArray);
this.getCurrentArray();
}
getCurrentArray() {
this.currentSoundArray = soundArray;
}
render(){
...
}
currently when i view the component, the componentDidMound will run once and console the sound array. At first, the sound array is empty:
[]
However, after i put value in the sound array and comeback to view the component, it wont print the console and it won't update the value of this.currentSoundArray
My expected result should be the currentSoundArray will be changed and print to the console every time the soundArray has been changed in another component. for example:
[]
[1,2]
[1,2,4]
componentDidMount() is invoked immediately after a component is mounted (inserted into the tree). Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
It runs only once.
What you are trying to do is access currentSoundArray value when it is updated from another component, now that you will not be able to do traditionally.
Also componentDidMount fires only once when the component is first initialized and rendered.
Solution 1
A better way of doing this is using something like React Redux to manage your application state, this way you would be able to access the states from any component throughout your application.
I have just finished setting up a boiler plate template for this exact thing, if you would like to check it out its on Github :)
Solution 2
If you are not interested in Redux then i would suggest you use react context for this, it will solve your issue as well. you can check out many examples online for example this uses context to share a snackbar across components.
Hope this Helps!

Why to use Higher order component [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I am displaying contact list array.
If contacts array is empty it will show the loader else will display contact list.
I render loader using higher order component Using this tutorial. For this I got performance summary as shown in the below image-
when i render loader using simple if else condition then i had performance graph as below -
comparing this i got to know that while using higher order component it requires more time than simple loop.
Can anyone please explain me which is better to use ? and when we should use the Higher order component ? what are advantages and disadvantages of using Higher order component ?
A higher order component allows you to apply functionality or data that is common amongst a number of components to a component and will return a new component with the functionality or data of the HoC included.
As for advantages or disadvantages. Would entirely depend on the circumstance and problem you are trying to address. You would also need to perform a long list of tests as the times are too close to really say one is quicker than the other. Also this looks like it is on your local so on production server could be an entirely different story.
But in your circumstance are you apply any extra functionality to your <Loader /> component? If you aren't or that functionality is not going to be used anywhere else then it might be unnecessary to use a HoC in your case.
ReactJS - Higher Order Components
pros for HOC:
extremly reusable around your app/projects:
// withShowSupport.js
export default Component => props =>
!props.show
? null
: <Component { ...props } />
easy testing
res:
https://www.robinwieruch.de/gentle-introduction-higher-order-components/
New technology can lead us to be more efficient and effective in productivity. But, of course, it will also increase resource usage.
I don't have enough knowledge to explain more, but I can give you simple study case.
I have a react app which consists of several pages (how about > 10 pages?). I want to do something when each page has been rendered (In other words, page changes). If-else condition rendering? No way!
Actually, you can make an HOC named withBase that will wrap each page (Use it when you export your page component e.g. export default withBase(Home)). withBase will execute a function that indicates page has been changed.
DEMO
As per definition :
HOC is a function that accepts your component as an argument and
returns a new function that adds some feature to the component.
A simple use case is - when you call an API to fetch some data and use them to render some content in your application, we need to show some kind of progress bar, loading indicator, etc to tell users that data is being fetched. We can use HOC for that purpose.A sample code goes here
import React from 'react';
import List from './List.js';
import WithLoading from './WithLoading.js';
const ListWithLoading = WithLoading(List);
class App extends React.Component {
state = {
loading: false,
repos: null
}
componentDidMount() {
this.setState({ loading: true });
fetch(`https://api.github.com/users/farskid/repos`)
.then(json => json.json())
.then(repos => {
this.setState({ loading: false, repos: repos });
});
}
render() {
return (
<ListWithLoading isLoading={this.state.loading} repos={this.state.repos} />
)
}
}
the above is App.js file and below is the HOC component WithLoading
import React from 'react';
function WithLoading(Component) {
return function WihLoadingComponent({ isLoading, ...props }) {
if (!isLoading) return (<Component {...props} />);
return (<p>Be Hold, fetching data may take some time :)</p>);
}
}
export default WithLoading;
so in App.js, we are calling HOC like const ListWithLoading = WithLoading(List); and <ListWithLoading isLoading={this.state.loading} repos={this.state.repos} />, Where List is the component which is passing into the HOC. based on the sLoading prop, loding symbol is shown. Another one interesting thing is HOC dont have a render menthod! beacuse its a simple function !
By my understanding, Higher-Order-Component adds an additional layer between components or libraries for better code-reuse.
For example, you have a library file "User.class.js" that is responsible to retrive/store user data, and it's used by different components. When "User.class.js" is modified, method names changed, or parameters changed. What you gonna do? Apply changes to all those components? What if it's used by 100 different components, or even more? With Higher-Order-Component, you just need to apply the changes to one single file.

Stateless functional component vs. additional render method in a stateful component?

As a really basic example, imagine I wanted to render a div containing some text outside of my render() method. Which of these options would be better?
class StatefulComponent extends Component {
...
render() {
return (
{this.renderTextDiv(this.state.text)}
)
}
renderTextDiv(text) {
return <div>text</div>
}
}
or
class StatefulComponent extends Component {
render() {
return (
<TextDiv text={this.state.text} />
)
}
}
function TextDiv({text}) {
return <div>{text}</div>;
}
Or would you completely pull the stateless component into its own class? Or does it just not matter at all? Does one make testing easier? Readability? Any differences at all?
It does not make any difference in terms of what is being displayed. However, it definitely changes the structure and readability of the code.
For myself, I try to divide the structure into as much Components as possible, and so does Thinking in react suggests. However, if you think that the element does not structurally differ from its parent component and thus does not deserve its own separate component but you require some readability and re-usability, the top code works.
The first one looks more concise in my opinion. You could render html in methods if it's not a big code, or, just a conditional rendering inside the component. Whenever you have some html rendering with a big structure and some functionality, it is always good to separate it into its proper component, because you probably would reuse this code later. Again: If it's not a big code or functionality, it's ok to use html rendering inside a method.

Passing more parameters to a pure render function in React

Lately I've been trying to write my React components as "Pure Functions" and I've noticed that sometimes I want to have something which feels a lot like state. I was thinking about passing my state as a second parameter to my component. I can achieve this by calling my component as a normal function with two parameters, props and state.
For example:
// abstracted to it's own module
const useState = (Component, state = {}) => {
return class extends React.Component {
state = createState(this, state); // will traverse and update the state
render() {
const { props, state } = this;
return Component(props, state); // <-- call the Component directly
}
};
};
const Component = (props, { index, increase }) => (
<div onClick={increase} {...props}>
Click me to increase: {index}
</div>
);
const componentState = {
index: 0,
increase: (event, state) => ({ ...state, index: state.index + 1 })
};
const StatefullComponent = useState(Component, componentState);
<StatefullComponent style={{ color: "purple" }} />;
I have a CodeSandbox example:
My questions are:
Will this pattern harm performance?
I'm no longer extending the props with state values, this might be a good thing
I am messing with the way components are rendered by default, this might be a bad thing
Will this Pattern break things like shouldComponentUpdate? (I have a sinking feeling this is modelling the old context api)
How worried should I be that future react updates will break this code?
Is there a more "Reacty" way of using State in a Pure function without resorting to libraries like Redux?
Am I trying to solve something which should not be solved?
Note: I'm using state in this example, but it could also be a theme, authorisation rules or other things you might want passed into your component.
EDIT 19-03-2018: I have noticed that people seem to be confused about what I'm asking. I'm not looking for a new framework or a conversation about "why do you want to separate your concerns?". I am quite sure this pattern will clean up my code and make it more testable and "cleaner" in general. I really want to know if the React framework will in any way hinder this pattern.
At first glanced when I checked your code I had a question:
"Why do you make it so complicated? When you can simply make it with a class declaration".
But later when I have splitted your code I found it really worth to do that.
Question 1: Doesn't really make a difference, it is the way how HOC does the composition.
I'm no longer extending the props with state values, this might be a good thing
Why/When might it be a good thing?
I am messing with the way components are rendered by default, this might be a bad thing
I don't see that you break or mess the rendering by default, I think the HOC pattern promotes the same philosophy, the difference you separate state from props.
Question 2: If a developer decide to use a stateless component then he/she should realize all “lifecycle methods” or references ref will be not available.
Your pattern make stateless component as “statefull” but in stateless declaration - amazing 😋.
Like in JSX you write in JS an "HTML" and inside it JS code with another "HTML":
<ul>
{list.map(text => <li>text</li>)} // I know there should be used key
</ul>
Mr. Baudin pattern (state-full like stateless):
import React from 'react'
import {useState} from './lib'
const state = {
index: 0,
increase: (event, state) => ({index: state.index + 1})
}
const Component = (props, state) => (
<div onClick={state.increase} {...props}>
Click me to increase: {state.index}
</div>
)
export default useState(Component, state)
Question 3: It depends what break changes will be in coming versions.
Question 4: Well... I don't think the offered pattern (implemented library) can be considered as application state management but it can be used within any state management like Redux or Mobx because it deals with internal component state.
Question 5: No, I don't think. Your solution makes code less and clean. Functional components are good for very simple or representational components and now it can be extended with state.
While this question has been open I've done some painful research on the subject and I'd like to share this research with you.
Question 1: Performance; Calling your components as functions or even as constructor functions doesn't really make a difference. You simply get your component instead of a type.
// the component
const MyComponent = () => (<div>This is my page</div>);
console.log(MyComponent());
console.log(new MyComponent());
console.log(<MyComponent />);
console.log(React.createElement(MyComponent));
Pen (Don't forget to inspect the developer tools!)
What I've noticed is that when you call a component directly you lose a little information, for example, when I use JSX the type information is preserved:
React.createElement(MyComponent).type === MyComponent // <- true
MyComponent() // <- Now way to find out what constructed this...
This doesn't seem like a big deal because the MyComponent() is seen as a normal div so it should render correctly; but I can imagine that React might do some lookup on the type of the component and calling your function like this that might interfere with the performance.
Haven't found anything in the documentation nor in the source code to suggest that this is the case, so I see no reason to worry about performance at this point.
Question 2: Does this break shouldComponentUpdate; the answer is "maybe not", but not because I need to write a class as was suggested. The problem is that React does a shallow compare on the props when you use a PureComponent and with pure functions just expects that with the same props you get the same result. In my case, because of the second parameter it might think the component doesn't need to update but actually it should. Because of some magic in my implementation this seems to work for child components of a root component wrapped with the useState function.
This is as I expected the same problem as with the original implementation of the context api. And as such I should be able to solve it using some reactive techniques.
Question 3: Seeing how "just calling a component as a function" seems to be the entire idea behind react and seeing how it results in almost exactly the same component without the original type information I see no reason why this should break in the future.
Question 4/5: No, there is no more "Reacty" way of really solving this problem. There is how ever a more functional way. I could use a state monad and lift the entire thing up; but that would envolve a lot of work and I really can't see the benefit of doing that. Passing state as a second parameter seems, at least for now, as something which might be strange but viable and actually feasable.
Question 5: When I started looking around I didn't find a lot os answers to these questions, but now that I've really dug myself in I can see a few other libraries doing the same thing. For example: recompose which calls itself "lodash for react". They seem to use this pattern of wrapping your component in a function and returning a class a lot. (Their withState implementation).
Extra information: My conclusion is that this pattern (because it's nothing more than a pattern) is valid and does not break any fundamental rules of React. Just to give a little bit of extra information Bernardo Ferreira Bastos Braga wrote that I needed to use a class to do it "the React way". I fail to see how wrapping your function and returning a class with state is anything other than "using a class".
I do however realise that wrapping a function increases complexity, but not by much; function calls are really optimised and because you write for maintainability and optimise later.
One of my biggest fears is that when the software gets more and more complocated and we get more cross-cutting concerns to deal with, it will get harder and harder to handle every concern as a parameter. In this case it might be good to use a destructuring pattern to get the concerns which you need from a "concerns" obejct passed as the second parameter.
One last thing about this pattern. I've done a small test (Just selenium rendering a page a 100 times) and this pattern, on a small scale, is faster than using Redux. The bigger your redux state gets and the more components you connect the faster this pattern becomes. The down side is that you are now doing a bit of manual state management, this comes with a real cost in complexity. Just remember to weigh all options.
A few examples of why this state component
Applications which interact with users, require that you try to keep track of the interactions they have. These interactions can be modeled in different ways but I really like a stateful approach. This means that you 'thread' state through your application. Now in react you have a few ways of creating components. The three I want o mention are:
create a class and extend from Component
create a class and extend from PureComponent
create a stateless function
I really like the last option but, to be honest, it's a pain keeping your code performant. There are a lot of articles our there explaining how lambda expression will create a new function every time your component is called, breaking the shallow compare of the props done by PureComponent.
To counteract this I use a pattern where I wrap my stateless component in a HoC where I pass my component and my state object. This HoC does some magic and passes the state as a second parameter to the stateless function, ensuring that when the props are tested by the compare of the PureComponent it should work.
Now to make the wrapper even better I memoize the lambdas so that only a single reference to that function exists so that even if you were to test the function by reference it should still be OK.
The code I use for this is:
return Object.entries(_state).reduce(
(acc, entry) => {
const [key, value] = entry;
if (value instanceof Function) {
acc[key] = _.memoize(item => (...args) => {
const newState = value.apply(null, [...args, root.state, root.props]);
root.setState(newState);
});
} else {
acc[key] = value;
}
return acc;
},
{}
);
};
As you can see I memoize the function and call it proxying the arguments and passing in the state and the props. This works as long as you can call these functions with a unique object like so:
const MyComponent = useState((props, { items, setTitle }) => {
return (
<div>
{items.map(item => (
<Component key={item.id} item={item} changeItem={setTitle(item)} />
))}
</div>
);
}, state);
1- Will this pattern harm performance?
Performance is usually not a black/white, rather it is better / worse in different scenarios. Since React already has a standard way of doing this, it it plausible that you'll be missing out on internal optimizations.
2-Will this Pattern break things like shouldComponentUpdate? (I have a sinking feeling this is modelling the old context api)
Yes, you should be using the class declaration if you need to write shouldComponentUpdate functions
3- How worried should I be that future react updates will break this code?
I think is fair to say that you should, since there are obvious and documented ways of doing the same using classes.
4 - Is there a more "Reacty" way of using State in a Pure function without resorting to libraries like Redux?
you could have a container component that has state and pass down callback functions to update the state
5- Am I trying to solve something which should not be solved?
yes, since there is already a mainstream and documented way of archieving what you need using the Component class. You should probably resort to functional components only for very simple or presentational components

Resources