Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么我的React上下文助手函数使用过时的状态?_Javascript_Reactjs_Typescript_React Native - Fatal编程技术网

Javascript 为什么我的React上下文助手函数使用过时的状态?

Javascript 为什么我的React上下文助手函数使用过时的状态?,javascript,reactjs,typescript,react-native,Javascript,Reactjs,Typescript,React Native,谢谢你看这个 这是我的问题;在我的react原生应用程序中,我编写了一个react上下文,用于管理“标题消息”,我可以在代码库中的任何位置调用这些消息,并在我的应用程序的标题元素下附加一条消息(全局显示)。这个过程可以正常工作,我可以使用helper函数呈现我添加的第一个头消息。addNewMessage('id','JSX.Element');但当我再次这样称呼时;将删除上一条消息,并显示新消息 我认为这是因为在下面共享的上下文中定义的函数.addNewMessage()引用了状态。。。调用它

谢谢你看这个

这是我的问题;在我的react原生应用程序中,我编写了一个react上下文,用于管理“标题消息”,我可以在代码库中的任何位置调用这些消息,并在我的应用程序的标题元素下附加一条消息(全局显示)。这个过程可以正常工作,我可以使用helper函数呈现我添加的第一个头消息。addNewMessage('id','JSX.Element');但当我再次这样称呼时;将删除上一条消息,并显示新消息

我认为这是因为在下面共享的上下文中定义的函数.addNewMessage()引用了状态。。。调用它更新状态。。。然后再叫它;它仍然引用原始状态。。。请参阅控制台日志,以了解这在两个后续调用中的效果

背景背后的代码;助手函数在函数中声明。。。
import*as React from'React';
从“react native”导入{Text};
导出接口元素{
[key:string]:JSX.Element;
}
导出接口IState{
设置状态:(newState:IState)=>无效;
addNewMessage:(id:string,elem:JSX.Element)=>void;
removeMessage:(id:string)=>void;
returnAllMessages:()=>JSX.Element[]
信息:IELENTS;
}
导出接口IProps{
子元素:JSX.Element[]| JSX.Element;
}
常量默认值:IState={
设置状态:()=>未定义,
addNewMessage:()=>未定义,
removeMessage:()=>未定义,
returnAllMessages:()=>[],
消息:{'test1':FooBarLoremIpsum},
};
export const headerMessageContext:React.Context=React.createContext(默认值);
const CTX_HeaderMessages:React.FC=(道具:IProps)=>{
const[state,updateState]=React.useState(默认值);
//每次我调用这个函数时,它的行为就像在使用
//defaultValues而不是state…我认为这是一个奇怪的副作用
//定义一个函数,然后将该函数的实例存储在
//状态对象本身…?但每当我试图声明一个副作用时
//这将本质上存储函数的一个新实例;我发现自己
//在一个无限循环中…我正在与这里的模式进行斗争,以使其工作:/
const addNewMessage=(id:string,elem:JSX.Element)=>{
log('进入“AddNewMessage”的状态,状态);
const newMessages={…state.messages};
newMessages[id]=elem;
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]);
常量值:IState={
状态
设置状态:更新状态,
添加新消息,
removeMessage,
返回所有消息
}
返回(
{props.children}
);
};
导出默认CTX_标头消息;
Chrome控制台日志 这些日志显示了我的经历。。。我想提请您注意messages对象的价值。当我第一次调用函数时;增值;当我第二次调用函数时;请注意,第一次调用(上一行)的值不存在

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

我认为在你的上下文中传递setState是多余的。您只需要在您的状态中存储消息,而不是CRUD方法。看看下面的代码,我想它会工作的

import * as React from 'react';
import { Text } from 'react-native';

export interface IElements {
  [key: string] : JSX.Element;
}

export interface IState {
  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 = {
  addNewMessage: () => undefined,
  removeMessage: () => undefined,
  returnAllMessages: () => [],
  messages: { test1: <Text>FooBarLoremIpsum</Text> },
};

const defaultMessages : IElements = {
  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<IElements>(defaultMessages);

  // 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 };
    newMessages[id] = elem;
    console.log('State Exiting "AddNewMessage"', newMessages);
    updateState(newMessages);
  };
  const removeMessage = (id: string) => { if (state[id]) { delete state[id]; } };
  const returnAllMessages = () => Object.keys(state).map((key) => state[key]);

  const val: IState = {
    messages: state,
    addNewMessage,
    removeMessage,
    returnAllMessages,
  };

  return (
    <HeaderMessagesContext.Provider value={val}>
      {props.children}
    </HeaderMessagesContext.Provider>
  );
};

export default CTX_HeaderMessages;
import*as React from'React';
从“react native”导入{Text};
导出接口元素{
[key:string]:JSX.Element;
}
导出接口IState{
addNewMessage:(id:string,elem:JSX.Element)=>void;
removeMessage:(id:string)=>void;
returnAllMessages:()=>JSX.Element[]
信息:IELENTS;
}
导出接口IProps{
子元素:JSX.Element[]| JSX.Element;
}
常量默认值:IState={
addNewMessage:()=>未定义,
removeMessage:()=>未定义,
returnAllMessages:()=>[],
消息:{test1:FooBarLoremIpsum},
};
常量默认消息:IEElements={
消息:{test1:FooBarLoremIpsum},
};
export const headerMessageContext:React.Context=React.createContext(默认值);
const CTX_HeaderMessages:React.FC=(道具:IProps)=>{
const[state,updateState]=React.useState(defaultMessages);
//每次我调用这个函数时,它的行为就像在使用
//defaultValues而不是state…我认为这是一个奇怪的副作用
//定义一个函数,然后将该函数的实例存储在
//状态对象本身…?但每当我试图声明一个副作用时
//这将本质上存储函数的一个新实例;我发现自己
//在一个无限循环中…我正在与这里的模式进行斗争,以使其工作:/
const addNewMessage=(id:string,elem:JSX.Element)=>{
log('进入“AddNewMessage”的状态,状态);
const newMessages={…state};
newMessages[id]=elem;
log('正在退出“AddNewMessage”的状态,newMessages);
更新(新消息);
};
const removeMessage=(id:string)=>{if(state[id]){delete state[id];};
const returnAllMessages=()=>Object.keys(state.map)((key)=>state[key]);
常量值:IState={
信息:国家,
添加新消息,
removeMessage,
返回所有消息,
};
返回(
{props.children}
);
};
导出默认CTX_标头消息;

您的代码应该看起来正常,唯一看起来奇怪的方法是removeMessage方法,您应该始终保持状态尽可能纯净,因此您应该克隆您的状态,而不使用要删除的消息id,因此,现在您正在修改状态引用,而不是使用新的一个对象状态更新状态,而没有需要删除的消息
delete
将无法正常工作,更改将无法自行传播。您需要创建一个n