Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6211

Why do my React Context Helper functions use outdated state?

$
0
0

Thank you for taking a look at this...

Here's my problem; in my react native app I have written a React Context that manages "Header Messages" that I can call anywhere in the code base and attach a message under the Header element of my app (Displayed Globally). This process works and I am able to render my first Header Message that I add using the helper function .addNewMessage('id', 'JSX.Element'); but when I call this again; the previous message is removed and the new message is displayed...

I believe this is happening because because the function .addNewMessage() defined in the context shared below references state... Calling it updates state... then calling it again; its still referencing the original state... See the console logs to see how this plays out with two subsequent calls.

Code Behind the Context; Helper functions are declared in the function...

import * as React from 'react';import { Text } from 'react-native';export interface IElements {  [key: string] : JSX.Element;}export interface IState {  setState : (newState: IState) => void;  addNewMessage : (id: string, elem: JSX.Element) => void;  removeMessage : (id: string) => void;  returnAllMessages : () => JSX.Element[]  messages : IElements;}export interface IProps {  children : JSX.Element[] | JSX.Element;}const defaultValues: IState = {  setState: () => undefined,  addNewMessage: () => undefined,  removeMessage: () => undefined,  returnAllMessages: () => [],  messages : {'test1': <Text>FooBarLoremIpsum</Text>},};export const HeaderMessagesContext: React.Context<IState> = React.createContext<IState>(defaultValues);const CTX_HeaderMessages: React.FC<IProps> = (props: IProps) => {  const [state, updateState] = React.useState(defaultValues);  // Every time I call this function, it is acting like it is using  // defaultValues instead of state... I assume this is a weird side effect  // of defining a function then storing an instance of that function inside  // the state object itself...? But anytime I try and declare a side effect  // that would essentially store a new instance of the function; I find myself  // in an infinite Loop... I'm struggling with the pattern here to make this work :/  const addNewMessage = (id: string, elem : JSX.Element) => {    console.log('State Coming into "AddNewMessage"', state);    const newMessages = {...state.messages};    newMessages[id] = elem;    console.log('State Exiting "AddNewMessage"', {...state, messages : newMessages});    updateState({...state, messages : newMessages});  };  const removeMessage = (id: string) => { if(state.messages[id]) {delete state.messages[id]} }  const returnAllMessages = () => Object.keys(state.messages).map(key => state.messages[key]);  const val: IState = {    ...state,    setState : updateState,    addNewMessage,    removeMessage,    returnAllMessages  }  return (<HeaderMessagesContext.Provider value={val}>      {props.children}</HeaderMessagesContext.Provider>  );};export default CTX_HeaderMessages;

Chrome Console Logs

These logs show what I am experiencing... I'd like to draw your attention to the value of the messages object. When I call the function the first time; the value is added; when I call the function a second time; Notice the value from the first call (on the previous line) is not present...

State Comming into "AddNewMessage"    {messages: {…}, setState: ƒ, addNewMessage: ƒ, removeMessage: ƒ, returnAllMessages: ƒ}    addNewMessage: ƒ addNewMessage()    messages: {test1: {…}}    removeMessage: ƒ removeMessage()    returnAllMessages: ƒ returnAllMessages()    setState: ƒ setState()    __proto__: ObjectHeaderMessages.tsx:38 State Exiting "AddNewMessage"    {messages: {…}, setState: ƒ, addNewMessage: ƒ, removeMessage: ƒ, returnAllMessages: ƒ}    addNewMessage: ƒ addNewMessage()    messages: {test1: {…}, SuggestUpdate_Line78: {…}}    removeMessage: ƒ removeMessage()    returnAllMessages: ƒ returnAllMessages()    setState: ƒ setState()    __proto__: ObjectHeaderMessages.tsx:35 State Comming into "AddNewMessage"    {messages: {…}, setState: ƒ, addNewMessage: ƒ, removeMessage: ƒ, returnAllMessages: ƒ}    addNewMessage: ƒ addNewMessage()    messages: {test1: {…}}    removeMessage: ƒ removeMessage()    returnAllMessages: ƒ returnAllMessages()    setState: ƒ setState()    __proto__: ObjectHeaderMessages.tsx:38 State Exiting "AddNewMessage"    {messages: {…}, setState: ƒ, addNewMessage: ƒ, removeMessage: ƒ, returnAllMessages: ƒ}    addNewMessage: ƒ addNewMessage()    messages: {test1: {…}, SuggestUpdate_Line79: {…}}    removeMessage: ƒ removeMessage()    returnAllMessages: ƒ returnAllMessages()    setState: ƒ setState()    __proto__: Object

Viewing all articles
Browse latest Browse all 6211

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>