Access Object Values with Context API in Child Component

Viewed 260

I have the following object being exported into another file:

info.js

export const info = {
    companyName: '',
    title: 'Some title',
    year: '',
};

I'm importing this object into my Context.js like so:

InfoContext.js

import React, { useState, createContext } from 'react';
import {info} from './info'
export const InfoContext = createContext();

export const InfoProvider = ({ children }) => {
  const [state, setState] = useState({
        ...info,
    });
    return (
        <InfoContext.Provider value={[state, setState]}>
            {children}
        </InfoContext.Provider>
    );
};

What I want to do is access the object values from my state inside my App.js. - Here is what I have tried but I am not having any success:

App.js

import React from "react";
import { InfoProvider, InfoContext } from "./InfoContext";

export default function App() {
  return (
    <InfoProvider>
      <InfoContext.Consumer>
      {state => (
            <>
              <h1>{state.title}</h1>
            </>
          )}
      </InfoContext.Consumer>
      </InfoProvider>
  );
}

I'm clearly missing something obvious here. I've tried a few things but I'm not sure what the issue is. I feel it has something to do with my object being accessed from a separate file.

Additionally, here is a sandbox link with the above code. Any help would be greatly appreciated!

Code Sandbox

1 Answers

You are passing your value to Provider as array, but on Consumer you expecting it to be an Object.

You need to pass an Object instead:

<InfoContext.Provider value={{state, setState}}>

Also you are using Consumer wrong. As a callback it takes whole value that you've passed in Provider, not state:

<InfoContext.Consumer>
  {(value) => (
    <>
      <h1>{value.state.title}</h1>
    </>
  )}
</InfoContext.Consumer>

or using destructured assignment:

<InfoContext.Consumer>
  {({state}) => (
    <>
      <h1>{state.title}</h1>
    </>
  )}
</InfoContext.Consumer>

then you can use value.setState({...}) for example. etc. But note that this is a bad practice updating state like that.

Code Sandbox

Related