DEV Community

Cover image for Simple way for managing your props in React
Soo Yang, Tan
Soo Yang, Tan

Posted on

Simple way for managing your props in React

If you have been developing an application that uses React, you might run into a situation where it becomes difficult or messy to manage the component props. A common scenario would be passing global data such as authenticated user details to deeply nested components.

Below is a simple example to demonstrate the passing of props from a top level component containing the userDetails all the way to the child component that renders the details on a user profile page.

We have an App component with the authenticated user details (global data). For simplicity, we will define the userDetails as a constant. We will have a component that look something similar to the following:

App.js

const App = () => {  
  const userDetails = {
    name: "User1", 
    address: "NY", 
    status: "active", 
    dateJoined: "January 2019"
  }
  return (
    <Profile userDetails={userDetails}/>
  );
}

The App component will render the Profile component which will be the user profile page. In order for the userDetails to be available on our profile screen, we pass it as a prop to the Profile component.

Our Profile component will like the following:

class Profile extends Component {
    render() {
        const { userDetails } = this.props
        return (
            <React.Fragment>
                <PrimaryDetailsCard userDetails={userDetails} />
                <SecondaryDetailsCard userDetails={userDetails} />
            </React.Fragment>
        )
    }
}

Profile component will render PrimaryDetailsCard and SecondaryDetailsCard component which carries diffrent kind of CSS styles for rendering different kinds of user details for the profile page. We once again have to pass userDetails as a prop to PrimaryDetailsCard and SecondaryDetailsCard component.

Example of PrimaryDetailsCard and SecondaryDetailsCard code:

PrimaryDetailsCard.js
class PrimaryDetailsCard extends Component {
    render() {
        const { userDetails } = this.props
        return (
            <div>{userDetails.name}, {userDetails.dateJoined}</div>
        )
    }
}

SecondaryDetailsCard.js
class SecondaryDetailsCard extends Component {
    render() {
        const { userDetails } = this.props
        return (
            <div>{userDetails.address}</div>
        )
    }
}

The passing of props makes it hard to manage and it will get even more complex.

React.Context to the rescue!

We can avoid the hassle of passing props to multiple nested components especially if they do not need to know the details. We can use React.Context for that!

We start by declaring a UserContext in a new file using the built in function const UserContext = React.createContext({});.

Inside our example App.js, simply import the UserContext and use UserContext.Provider to wrap all the components.
The provider simply allows the children component to receive the context value.

import UserContext from './UserContext';

const App = () => {
  const userDetails = {
    name: 'User1',
    address: 'NY',
    status: 'active',
    dateJoined: 'January 2019',
  };
  return (
    <UserContext.Provider value={userDetails}>
      <Profile />
    </UserContext.Provider>
  )
};

Now that we have UserContext.Provider set up with the userDetails set as its value, our Profile component does not need any knowledge regarding userDetails, we can simply remove the codes relating to the userDetails.

class Profile extends Component {
  render() {
    return (
      <React.Fragment>
        <PrimaryDetailsCard />
        <SecondaryDetailsCard />
      </React.Fragment>
    );
  }
}

The next part would be obtaining the context value inside our child component that are interested in the values. Using PrimaryDetailsCard as an example:

import UserContext from './UserContext';

class PrimaryDetailsCard extends Component {
  render() {
    return (
        <UserContext.Consumer>
            {(userDetails) => {
                return(
                    <div>
                    {userDetails.name}, {userDetails.dateJoined}
                  </div>
                )
            } }
        </UserContext.Consumer>

    );
  }
}

We import the UserContext and wrap our component with UserContext.Consumer component. The Consumer component will enable our component to access the value which was previously set by the Provider. With that, we have organized our props neatly while displaying our User details on the profile page as usual!

You can learn more about React.Context here
You can checkout my sample code on:
1) Without React.Context
2) Using React.Context

Top comments (0)