DEV Community

Cover image for Bad ReactJs practices to avoid

Bad ReactJs practices to avoid

Juraj Pavlović on November 15, 2021

There are plenty of articles and blogs that contain useful information on how to do things the right way. Best practices, good design patterns, cle...
Collapse
 
jurajuki profile image
Juraj Pavlović

The issue with passing the prop to the initial state is that one may think the state will change if the prop does. This could make young developers confused. With that, your latter example makes much more sense. Keeping the state in a container and passing the state handlers down to the presentation component.

Thank you for your contribution.

Collapse
 
jamesthomson profile image
James Thomson

The issue with passing the prop to the initial state is that one may think the state will change if the prop does. This could make young developers confused.

I don't think that's a good enough reason. If you think this way, then you don't understand how React's lifecycle works and that's a far bigger problem - avoiding a perfectly acceptable practice (which is discussed within React's official docs) only accentuates that problem.

Thread Thread
 
jurajuki profile image
Juraj Pavlović

It doesn't make a lot of sense in a way of how a React app should have its state structured. If a prop is higher up in the component tree, it shouldn’t be used as a part of the separate state within a component. What is the benefit if you do such a thing? It makes sense to use the prop to determine the state implicitly, but not to directly copy the prop in the state. This is clearly a code smell and it is discouraged by many.
Another thing, regarding the React docs, I think you misread them. The link you provided only offers an example with useState and some initialState inside, it does not state or show using props as initialState. This is what actual docs say about it: “There should be a single “source of truth” for any data that changes in a React application.” and “If something can be derived from either props or state, it probably shouldn’t be in the state.” In another words using props to generate state often leads to duplication of “source of truth”, i.e. where the real data is. Meaning this is a bad practice.

Other than that, there are plenty other articles, blogs and the React docs covering this topic which agree with the stated:
reactjs.org/docs/lifting-state-up....
stackoverflow.com/questions/400634...
medium.com/@justintulk/react-anti-...
vhudyma-blog.eu/react-antipatterns...

Thread Thread
 
jamesthomson profile image
James Thomson

If a prop is higher up in the component tree, it shouldn’t be used as a part of the separate state within a component.

Well of course, but you wouldn't use initialState in that use case.

It makes sense to use the prop to determine the state implicitly, but not to directly copy the prop in the state. This is clearly a code smell an it is discouraged by many.

Yes, again, if you're doing this then you don't understand the use of initialState.

Another thing, regarding the React docs, I think you misread them. The link you provided only offers an example with useState and some initialState inside, it does not state or show using props as initialState.

No, it clearly has an example of exactly this:

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

This is what actual docs say about it: “There should be a single “source of truth” for any data that changes in a React application.” and “If something can be derived from either props or state, it probably shouldn’t be in the state.”

Yes, again, then you shouldn't be using initialState in that use case. If the initialState can change then it's not and initialState, it's a reactive prop.

I'm not sure what you're trying to prove with the links provided. My comment was that initialState isn't something bad as long as you know how to use it and placing a blanket "never use initialState" only avoids properly understanding the use case.

Even within the last link you provide the author goes into detail on proper use cases and states:

In general, props should be avoided in the initial state unless you only need them to initialize the internal state of the component and either props are never updated or the component should not react to their updates.

Let's look at the example above - we pass the initialValue prop, which is used to initialize the internal state of the ChildComponent and is never changed.

This is perfectly fine, but it is an exception rather than the general rule.

The real problem occurs when the initialValue in the ParentComponent can be changed

Which exactly reiterates my point - understanding React's lifecycle and the use of initialState.

Thread Thread
 
jurajuki profile image
Juraj Pavlović

Using initial state for generic components is perfectly fine. My initial point was one for outside generic components. That's why you see examples provided in the last comment. Will make an edit explaining in it in more detail.

Thread Thread
 
starver20 profile image
Starver

This was a very informative article and also this thread was a good discussions. What i get from this thread is that props can be used as initial state only when we are sure that the prop is not going to change or the component is not bothered by the change in prop.

Thread Thread
 
jurajuki profile image
Juraj Pavlović

Thats what this amazing community is for. Contributing even more to a post with a discussion makes each of us learn more. The Props in Initial State heading and content have been edited to provide more details. It should be more clear now when is it good and when it isn't to use such a thing. I kindly ask you to check it out.

Collapse
 
christiankozalla profile image
Christian Kozalla

I agree that derived state from props isn't a bad practice. Then again, writing a component like that may not always be intentional, but due to lack of experience with React. It is a common beginner's mistake. I think, that's why it is considered a bad practice altogether.

Your two examples of the Counter are nice, however they do not behave the same. First one is managing its on internal state, the second Counter is only a presentational component. Image you want many independent counters on the page, so you would need more than one instance of Counter.

I've recently read "Writing Resilient Components" by Dan Abramov

However, a common mistake when learning React is to copy props into state. (Example with class component) This might seem more intuitive at first if you used classes outside of React. However, by copying a prop into state you’re ignoring all updates to it. In the rare case that this behavior is intentional, make sure to call that prop initialColor or defaultColor to clarify that changes to it are ignored.

overreacted.io/writing-resilient-c...

If initialCount prop of your first Counter would change, would the instance update/re-render or not (like in Dan's example)?

Collapse
 
markerikson profile image
Mark Erikson

Yeah, I covered the "Context vs Redux" question in much more detail in my post Why React Context is Not a "State Management" Tool (and Why It Doesn't Replace Redux).

Also, since I did that "When to Reach for Redux" podcast interview, we've added a new RTK Query data fetching and caching API to Redux Toolkit, which solves the same use case as React Query, Apollo, Urql, and SWR. I've also added a new section on how to use RTK Query to the "Redux Essentials" tutorial as well.

Collapse
 
jurajuki profile image
Juraj Pavlović

Your articles about Redux and how Redux compares to Context are incredibly thorough and well written. I specially loved them and mentioned one of them in the resources. Thank you so much for stopping by!

 
jurajuki profile image
Juraj Pavlović

Now this example makes me understand your initial point more clearly. In such cases I agree with you completely. When making such generic components to be used throughout the app, it makes sense. Thank you.

Collapse
 
reotech profile image
Reotech

So if we don't use index as key..please what should we use as key then?

Collapse
 
jurajuki profile image
Juraj Pavlović • Edited

Good question! One major thing to avoid alongside index is random keys such as uuid. A proper key should be a unique identifier from the data object you are passing. Check out the following example: Keys Example

Collapse
 
multiwebinc profile image
Mike Robinson • Edited

Instead of uuid, you could use this function that just returns an incrementing integer (guaranteed to be unique and no external dependencies):

var getNextKey = (function(n) {
  return () => ++n;
}(0));
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jamesthomson profile image
James Thomson

One major thing to avoid alongside index is random keys such as uuid
All you need to avoid is setting the key an each render. It's perfectly fine to use a uuid if you define it as part of the object being consumed and that uuid persists.

Thread Thread
 
jurajuki profile image
Juraj Pavlović

Indeed, if the uuid is a part of the object, then of course it is fine to use it. That way it is not a random key like I've mentioned.

Collapse
 
reotech profile image
Reotech

Thank you for this

Collapse
 
cteyton profile image
Cédric Teyton

Hi there, FYI we've added your blog post on a GitHub project gathering content about best coding practices :)
github.com/promyze/best-coding-pra...

Collapse
 
hasnab profile image
hasn-ab

Agreed completely.
Another case could be when we know for sure that props may not change.

Collapse
 
cgatian profile image
Chaz Gatian

Do you mind providing an example of what you mean by "Declaring components inside of components"?

Good article, thank you.

Collapse
 
jurajuki profile image
Juraj Pavlović

Of course I don't mind, here is an example of it:
declaring components inside of components

Keep in mind that this is a bad practice

Collapse
 
reotech profile image
Reotech

True true..thank you

Collapse
 
alfredosalzillo profile image
Alfredo Salzillo

Declaring components inside of components
is not a bad practice is wrong

 
christiankozalla profile image
Christian Kozalla

That statement was referring to class components, assigning the prop to state inside the constructor.

Anyways, thank you for clarifying!

Collapse
 
tanth1993 profile image
tanth1993

I think Using props in Initial State in case we need to update data from props. ex: a input field needs defaultValue is prop then we change it and the new data in state.