1

I'm new to context so may be a very easy error. I'm getting this error when triing to update the context:

[Unhandled promise rejection: TypeError: setUserInfo is not a function. (In 'setUserInfo(newUser)', 'setUserInfo' is undefined)]

Here is what I've done: AppContext.js

import React, { Component } from 'react'

const AppContext = React.createContext();

class UserProvider extends Component {
  // Context state
  state = {
    userInfo: {},
    userChats: {},
    userSettings: {},
  }

  // Method to update state
  setUserInfo = (user) => {
    this.setState((prevState) => ({ user }))
  }
  
  // Method to update state
  setUserChats = (userChats) => {
    this.setState((prevState) => ({ userChats }))
  }
  
  // Method to update state
  setUserSettings = (settings) => {
    this.setState((prevState) => ({ settings }))
  }
  
  render() {
    const { children } = this.props
    const { userInfo } = this.state
    const { setUserInfo } = this
    const { userChats } = this.state
    const { setUserChats } = this
    const { userSettings } = this.state
    const { setUserSettings } = this

    return (
      <UserContext.Provider
        value={{
          userInfo,
          setUserInfo,
          userChats,
          setUserChats,
          userSettings,
          setUserSettings,
        }}
      >
        {children}
      </UserContext.Provider>
    )
  }
}

export default AppContext

export { UserProvider }

Wrapping the App Component:

const defaultProviderValue = {userInfo: {}, userChats: {}, userSettings: {}} 

<AppContext.Provider value = {defaultProviderValue}>
    <Container>
        <AppNavigator />
    </Container>
</AppContext.Provider>

and then finally trying to update it on a class component:

import React, { Component} from 'react';

import AppContext from '../Context/AppContext.js'

class startScreen extends Component {
    static contextType = AppContext
     
    constructor(props) {
        super(props);
        this.state = {
        };
    }

    async componentDidMount() {
        const { userInfo, setUserInfo } = this.context
        
        console.log("CONTEXT!!!!! : " + JSON.stringify(userInfo));
    
        const newUser = { name: 'Joe', loggedIn: true };
        
        setUserInfo(newUser);  // ERROR fired: [Unhandled promise rejection: TypeError: setUserInfo is not a function. (In 'setUserInfo(newUser)', 'setUserInfo' is undefined)]

        console.log("NEW     CONTEXT!!!!! : " + JSON.stringify(userInfo));
    

    }

   render() {
        return(null);
   }
}

export default startScreen;

So how can I solve the error? It seems that can not find the method to update the value, but it's defined.

Marco Martin
  • 185
  • 1
  • 4
  • 18

1 Answers1

1

You are trying to use AppContext but you haven't set anything on itt apart from defaultValues. I guess you would want to use UserProvider and use AppContext within it

import React, { Component } from 'react'

const AppContext = React.createContext();

class UserProvider extends Component {
  // Context state
  state = {
    userInfo: {},
    userChats: {},
    userSettings: {},
  }

  // Method to update state
  setUserInfo = (user) => {
    this.setState((prevState) => ({ user }))
  }
  
  // Method to update state
  setUserChats = (userChats) => {
    this.setState((prevState) => ({ userChats }))
  }
  
  // Method to update state
  setUserSettings = (settings) => {
    this.setState((prevState) => ({ settings }))
  }
  
  render() {
    const { children } = this.props
    const { userInfo } = this.state
    const { setUserInfo } = this
    const { userChats } = this.state
    const { setUserChats } = this
    const { userSettings } = this.state
    const { setUserSettings } = this

    return (
      <AppContext.Provider
        value={{
          userInfo,
          setUserInfo,
          userChats,
          setUserChats,
          userSettings,
          setUserSettings,
        }}
      >
        {children}
      </AppContext.Provider>
    )
  }
}

export default AppContext;

export { UserProvider };

<UserProvider>
    <Container>
        <AppNavigator />
    </Container>
</UserProvider>

Post this change, you will be able to consume the context correctly

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • Thanks! The error is gone! But the context is not updated, the console log I got: CONTEXT!!!!! : {} NEW CONTEXT!!!!! : {}........ Maybe is async problem? – Marco Martin Mar 19 '21 at 09:25
  • `setUserInfo(newUser); console.log("NEW CONTEXT!!!!! : " + JSON.stringify(userInfo));` If you are expecting the new user value tto immediately reflect aftter setUserInfo, it won't work sincee setState is asynchronous. You can check [this post](https://stackoverflow.com/questions/41278385/setstate-doesnt-update-the-state-immediately/41278440#41278440) for more details – Shubham Khatri Mar 19 '21 at 10:22