Search code examples
reactjsreact-contextreact-functional-component

How to change context value in functional component?


I have a context named StatusContext like this:

export const statusCtxInit = {
    open: false,
    toggleOpen() {
        this.open = !this.open;
    }
};

const StatusContext = React.createContext(statusCtxInit);
export default StatusContext

The whole app is wrapping with the provider:

// ...
<StatusContext.Provider value={statusCtxInit}>
// ...

To use the values of my context I use useContext in my FC and it works when I get the value.

function MyComp() {
    const status = useContext(StatusContext);
    return (
        <div>
            {status.open
                ? `It's Open`
                : `It's Closed`}

            <button onClick={() => status.toggleOpen()}>
                Toggle
            </button>
        </div>
    )
}

export default MyComp

On the other hand, I also want to change the context by calling the toggleOpen but, it does not work as I want. Actually the value changes but not effect the MyComp.

What I did wrong? What shall I do?


Solution

  • import React from 'react';
    
    const statusContext = React.createContext();
    const {Provider} = statusContext;
    // custom provider
    export const StatusProvider = ({children}) => {
      const [isOpen, setOpen] = React.useState(false)
      const toggle = () => setOpen(v => !v)
      return (
        <Provider value={{isOpen, toggle}}>
          {children}
        </Provider>
      )
    }
    
    //custom hook
    export const useStatus = () => React.useContext(StatusContext)
    
    //usage
    function MyComp() {
      const status = useStatus()
      return (
        <div>
          {status.isOpen
            ? `It's Open`
            : `It's Closed`}
    
          <button onClick={() => status.toggle()}>
            Toggle
          </button>
        </div>
      )
    }
    
    export default MyComp