loading...
Cover image for ReactJS State Management: A Beginner's Perspective

ReactJS State Management: A Beginner's Perspective

dylanmesty profile image Dylan Mestyanek ・7 min read

I vividly remember my first encounter with state in React, it was rather confusing. So, you're telling me, if I have a list of tasty sandwiches in one component, I can't have that list of information in another component?

I was faced with a smirk and a laugh. Ofcourse you can, you just need to pass that information as props. Confused more than before, I took my best stab at comprehending props. My initial impression? How is this more convenient, than just grabbing something from the DOM with vanilla JS?

As I continued to build, things started to make a bit more sense:

  • React applications can hold state, which is a chunk of information
  • Other components can access that state by being passed as props
  • Parent components can't receive props from child components

I understood some of the textbook rules about React, but when I would begin to build on my own, I'd consistently run into similar problems.

  • Wait, there is no way this component could receive the props it needs..
  • Should the state be held in ThisComponent.js or ThatComponent.js?
  • Can I please go back to Vanilla JS already?

React seemed unmotivating to say the least. This confusion persisted for a while, until I had my first few beginner applications under my belt; however, the question would still resurface:

Where should I hold my state in React?

I want to explain from my beginner experience, what has helped me make sense of React state, and make some-what logical decisions on where to store it. This isn't including any advanced state management systems, just simply storing state within components in React. Now.. let's begin!

Consider what components need the state

For most examples, I'll be considering small applications, similar to the size of a to-do list, for simplicity. Maybe 3 or 4 child components. In a situation like this, there isn't any harm in holding most state within App.js.

This is typically the core of your app, it holds most of the routes to other components, renders some of the main components, and thus, makes sense to have state stored here.

When you take into consideration the fact that children components can not pass props back up to the parent component, it doesn't make sense to have the primary, important state in a child component.

There are so many different examples that could be painted here, but let's keep it simple.

function App() {
  const [veryImportantStuff, setVeryImportantStuff] = useState([An array of important stuff!])

    return (
        <div className="this-is-an-example">
            <h1>This is extremely important!</h1>
            <ThisComponent />
            <ThatComponent />
        </div>
    );
  }

In this example, we have our application, holding veryImportantStuff. Let's say that ThisComponent.js and ThatComponent.js both need access to it. It makes sense to hold the state here, that way we can pass the props to both of them:

function App() {
  const [veryImportantStuff, setVeryImportantStuff] = useState([An array of important stuff!])

    return (
        <div className="this-is-an-example">
            <h1>This is extremely important!</h1>
            <ThisComponent theseAreProps={veryImportantStuff} />
            <ThatComponent theseAreProps={veryImportantStuff} />
        </div>
    );
  }

Cool! However, what if ThatComponent only needs the state? Well it wouldn't make sense to keep it in App.js if you know for a fact none of the other components will need it. Because, remember, if state is stored in ThatComponent then App and ThisComponent can't access that state through props, due to not being able to pass props to parent components.

In this case, App.js is a parent component, because it is what is rendering ThatComponent and ThisComponent. ThisComponent is not considered a parent component of ThatComponent, but it still can't access the state within ThatComponent because ThisComponent is held within App.

I know, a bit confusing? It's a simple concept but for this example, it makes sense to keep state in the upper level of the application, App.js.

Ensure your state isn't held too far away from these components

Another tricky example is considering how deep your state is needed. This conversation could go on for hours, and how you want to place your state; however, for the sake of simplicity, let's consider that none of the other components need the state besides one child component.

Here we have App.js not holding any state:

function App() {
    return (
        <div className="this-is-an-example">
            <h1>This is extremely important!</h1>
            <ThisComponent />
            <ThatComponent />
        </div>
    );
  }

Here we have ThatComponent.js holding state, and ThatComponent.js is now rendering a child component, AChildComponent:

  function ThatComponent() {
    const [veryImportantStuff, setVeryImportantStuff] = useState([An array of important stuff!])

      return (
          <div className="hi-dev-community">
              <h1>We are inside a child component of App.js!</h1>
              <AChildComponent veryImportantStuff={veryImportantStuff} />
          </div>
      );
    }

So let's imagine that in the original parent component, App.js, neither the App, nor ThisComponent need the state. So we placed it within ThatComponent. Now ThatComponent has a child, AChildComponent.

Again, it is a list of very important information. Similar to our first example, if only AChildComponent needed access to the state, we would hold it there, but let's pretend both components need the state, ThatComponent and AChildComponent. So, we hold it in ThatComponent.

Remember, this is where the planning comes into play. App.js can't access this state now, through standard prop passing methods, so be sure to consider all use-cases of the state to ensure you don't need the state anywhere else.

Sometimes it comes down to personal preference

You go to someone's house for the first time, you walk into their kitchen, and that questions strikes you...

Where on earth is their silverware?

Everyone can relate to this question, there are 15-25 drawers, and you try to guess where it makes the most logical sense to store the silverware. However, 9/10 times, you guess wrong!

It's completely personal preference on how that individual wants to store their silverware, dishes, mugs, etc.

Wait, that sounds like "storing things", similar to, "storing items", similar to... "storing state", in React!

My point exactly! At times, it is personal preference. A lot of situations in programming can be gone about a variety of different ways, yet still yield the same result. It's the beauty of programming! But, it's also the reason being in other's kitchens is so confusing sometimes.

There have been several encounters of what I like to call, "chaos state". You may be wondering, what is chaos state? Well, I'm glad you ask!

In short, chaos state, is when you open the drawer in the kitchen that you expect to hold the silverware, and you find pencils, pens, and ducktape. So then you check the next drawer that makes the most logical sense in your mind, and to your surprise, it's full of dog cookies, and leashes!

By the time you find where the silverware is, it's tucked away in a secret corner, without any convenience of retrieving a fork or spoon, when you need it the most!

It leaves you wondering, why on earth would they store the silverware there?

It's the same situation when holding state in React! Various times I have taken a look inside of an application, and my mind is bewildered on the state management because it lacks reusability! However, if it was one level higher in the component tree, it would make far more sense to me!

To my point exactly: personal preference. Everyone goes about solving these situations differently, that's where it's your job to understand and adapt to these odd encounters.

You are going to make poor decisions!

To my final point, you are going to plan poorly, and place your state in silly places.

We all know the feeling, you are having your first dinner in your new home, you sit down at the table, and forget to grab silverware! You stand up to grab some forks and knives for the table, and you instantly think: Why would I have chosen this drawer to store all of my silverware? It doesn't make sense!

We all encounter this situation in our application at some point.

Why did I place the state here?

What's great about that feeling, is it shows your critical-thinking brain muscles are flexing! You see a way to improve the efficiency of how the app is currently set up, and you modify it!

However, it goes without saying, no amount of planning can counteract this. While planning is essential and extremely important for projects, things will come up that you did not plan for. Adjustments will have to be made, and that's part of the fun!

For example, what if your silverware collection grows exponentially, and your drawer is no longer large enough to hold all of your silverware/utensils!

In programming terms, what if your state becomes so large, it's inconvenient to hold it directly within a component?!

(That's when you break out the ol' trusty state management systems like Context or Redux! :D)

Okay, enough kitchen references! All finished!

Wrapping it up

Let me preface this by saying, these are extremely basic, beginner concepts when it comes to state in React. However, I know within my first encounter with React I was dearly lost, and many friends who have looked at it for the first time as well, failed to understand why React was useful.

I wanted to explain a very basic level of state in React. I didn't want to bring in advanced methods of state management, as it's already difficult enough to wrap your head around state and props. Including another layer of information would only make my beginner-level introduction, that more confusing!

I'm sure there are millions of different approaches to state management in React, these are just some examples and analogies that helped me wrap my head around it initially. Hopefully someone can find it valuable! :)

I would really enjoy hearing about your first experiences with ReactJS! What has helped you wrap your head around state and props? Was there any analogies, or situations, that really cleared things up for you? Let me know! :D

Discussion

pic
Editor guide
Collapse
fantasticsoul profile image
幻魂

I recommend u try concent, it is born for react, and power react from inside to outside.

feature 1 predictable:
concent take over react.setState, and dispatch feature is base on setState, so every state changing behavior is predictable, no matter use setState or dispatch
see demo below:
stackblitz.com/edit/cc-zero-cost-use

feature 2 zero-cost-use:
cause setState can be interactive with store, so you can use concent by register api on your classical react class writing without changing any code.
see demo below:
stackblitz.com/edit/cc-course-hell...

feature 3 progressive
you can separate your business logic code to reducer from class later. it will keep your view clean.
see demo below:
stackblitz.com/edit/cc-multi-ways-...

feature 4 high performance
with watchedKeys, renderKey, lazyDispatch, delayBroadcast features, concent render every view block only when it really need to been re-rendered
see watchedKeys demo:
stackblitz.com/edit/concent-watche...
see renderKey demo:
stackblitz.com/edit/concent-todoli...

feature 5 enhance react
computed, watch, effect, setup and etc... both of them are designed for react honestly
see demo below:
stackblitz.com/edit/hook-setup

because concent is quick new, so very less people know it, hope u can try it and give me feedback.

by the way: my en is not good, wish u understand what I said _^

Collapse
create1666 profile image
create1666

Wow - wish I could always get a breakdown like this for all had been learning..

You really understand it..

Can I take you as a mentor atleast?

I feel like starting all over with you.

Collapse
semantiking profile image