Coder Social home page Coder Social logo

2dynamicprovider's Introduction

Practice: Context Wrapper - Dynamic Provider

In the previous practice, you created your context and consumed it in the Detail component. Now you will make the context's value dynamic, which will give you a better sense of the true power of context!

Towards this end, in this practice, you will create a context provider to set the value of a context. You will then configure a component to read that value from the context whenever the value changes.

Setup

Click the Download Project button at the bottom of this page to go to the starter repo, then load the repo into [CodeSandbox].

Refactor the Context.Provider

The previous practice had you wrap your HoroscopeContext.Provider around the App component in src/index.js. While this works, it's not common practice. More often, developers will instead wrap the application in a provider component that they have created. That's what you will do now.

In your HoroscopeContext.js file, create a new component called HoroscopeProvider that takes in props as its parameter. For your return statement, use your HoroscopeContext provider component and wrap it around props.children. Once you've finished, export your new provider component as a default.

const HoroscopeProvider = props => {
  return (
    <HoroscopeContext.Provider>
      {props.children}
    </HoroscopeContext.Provider>
  );
};

Next, navigate to src/index.js. This is where you will use your HoroscopeProvider component, so import the component at the top of your file.

In your Root component, instead of using the HoroscopeContext.Provider component, wrap your App component with the HoroscopeProvider you just imported.

const Root = () => {
  return (
    <HoroscopeProvider>
      <App />
    </HoroscopeProvider>
  )
}

If all went well, your sandbox browser should still look the same. However, if you look at your component tree, you should be able to see your HoroscopeProvider in your browser's DevTools with Context.Provider nested inside and App inside Context.Provider.

This is what you should see:

Root
  \
  HoroscopeProvider
    \
    Context.Provider
      \
      App

Update the context value

If you look at the console tab in your sandbox browser's DevTools, you'll see another warning message from React about a missing value prop. You most definitely did not pass one into your HoroscopeContext provider this time, so let's do that with some state!

Back in the HoroscopeProvider component (src/context/HoroscopeContext.js), create a state variable currentSign and have the default value be any horoscope sign you want. Make sure it starts with a capital letter; this will be important later. If you don't know which sign to use, "Leo" is a good one, and it's only 3 characters long. (Did you remember to import useState?)

Once you have created your currentSign state, pass currentSign and setCurrentSign as the value in your HoroscopeContext.Provider. It should look something like this:

<HoroscopeContext.Provider value={{ currentSign, setCurrentSign }}>

Take another look at the React DevTools. If you click on the Context.Provider component, you should see the value set to currentSign and setCurrentSign in the props section.

Use context in the Detail component

You have created your context and wrapped your provider around your entire app. The final step you need to take is to consume your context and display the currentSign's details.

In src/components/Detail.js, you should have already imported useContext and HoroscopeContext. Inside your Detail component, now destructure currentSign, which comes from invoking useContext and passing in your HoroscopeContext as an argument.

const { currentSign } = useContext(HoroscopeContext);

Keep in mind, when you use the useContext hook and pass the context in, the value you get back will be the object you passed in as your value prop to the context provider. In this case, the object will look like this (which is why you can destructure):

{
  currentSign: "Leo",
  setCurrentSign: function (f)
}

In truth, you need more than just the name of the sign; you want to display details about the sign, such as its element and traits. This expanded data is located in src/data/horoscopes.js. Take a second to familiarize yourself with how the data is set up, including how it's being exported.

While you could import all this data into Detail.js and then use currentSign to grab the portion you need, a cleaner solution would simply include the relevant data in the context. That way, all the updating horoscope information will be included in one place--i.e., the horoscope context--for any subscribed component to access. This is the solution you will implement below.

At the top of your context/HoroscopeContext.js file, import the data from data/horoscopes.js as horoscopesObj. Next, inside the HoroscopeProvider component, create a new variable called sign and set it equal to the sign's object by keying into horoscopesObj using your currentSign state. Take a look at your horoscopesObj data again to help you see what you need.

Below is the object you're trying to access if your currentSign is "Leo".

{
  "name": "Leo",
  "date": "Jul 23 - Aug 22",
  "element": "Fire",
  "traits": "Proud, Bold, Ambitious",
  "backgroundImg": "https://www.horoscope.com/images-US/signs/profile-leo.png",
  "match": "Libra"
}

Your sign variable should look like this:

const sign = horoscopesObj[currentSign];

Once you have successfully grabbed the object, set the value on the Provider to include sign instead of currentSign:

<HoroscopeContext.Provider value={{ sign, setCurrentSign }}>

Back in your Detail component (components/Detail.js), destructure sign from the HoroscopeContext instead of currentSign. Now you should have everything you need! Update your <img> src, <h2>, and <h4> elements with the appropriate information from your sign object.

If all was done correctly, the Detail component should display all of your currentSign's information in the sandbox browser.

Head back to your HoroscopeContext.js and update your default state to another sign! Does your Detail component also update?

HOORAY!

You have successfully created a dynamic value in your context provider and consumed that context to display your currentSign's information.

What you have learned

Congratulations! In this practice you have learned how to

  1. Create a provider component that holds your Context.Provider
  2. Wrap your entire App with that provider component
  3. Set state variables as your provider component's value prop so that you can change the value dynamically
  4. Consume the context in another component
  5. Update (manually) your provider's default value and have that change reflected in another component

[CodeSandbox]: https://www.codesandbox.io# 2DynamicProvider

2dynamicprovider's People

Contributors

brandonlaursen avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.