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__: Object
HeaderMessages.tsx:38 State Exiting "AddNewMessage"
{messages: {…}, setState: ƒ, addNewMessage: ƒ, removeMessage: ƒ, returnAllMessages: ƒ}
addNewMessage: ƒ addNewMessage()
messages: {test1: {…}, SuggestUpdate_Line78: {…}}
removeMessage: ƒ removeMessage()
returnAllMessages: ƒ returnAllMessages()
setState: ƒ setState()
__proto__: Object
HeaderMessages.tsx:35 State Comming into "AddNewMessage"
{messages: {…}, setState: ƒ, addNewMessage: ƒ, removeMessage: ƒ, returnAllMessages: ƒ}
addNewMessage: ƒ addNewMessage()
messages: {test1: {…}}
removeMessage: ƒ removeMessage()
returnAllMessages: ƒ returnAllMessages()
setState: ƒ setState()
__proto__: Object
HeaderMessages.tsx:38 State Exiting "AddNewMessage"
{messages: {…}, setState: ƒ, addNewMessage: ƒ, removeMessage: ƒ, returnAllMessages: ƒ}
addNewMessage: ƒ addNewMessage()
messages: {test1: {…}, SuggestUpdate_Line79: {…}}
removeMessage: ƒ removeMessage()
returnAllMessages: ƒ returnAllMessages()
setState: ƒ setState()
__proto__: Object
Please login or Register to submit your answer