Javascript 反应useState和useEffect状态落后一步

Javascript 反应useState和useEffect状态落后一步,javascript,reactjs,typescript,react-hooks,Javascript,Reactjs,Typescript,React Hooks,我知道,出于性能原因,状态更新是异步和批处理的。知道我选择使用useState()和useffect()来等待状态更新,然后对其进行操作。我的问题是我的状态总是比它应该的状态落后一步 const myFunctionalComponent: React.FC<Props> = ( props: Props ) { const [lastRequestURL, setLastRequestURL] = useState<string>(); useEffect

我知道,出于性能原因,状态更新是异步和批处理的。知道我选择使用useState()和useffect()来等待状态更新,然后对其进行操作。我的问题是我的状态总是比它应该的状态落后一步

const myFunctionalComponent: React.FC<Props> = (
  props: Props
) {
  const [lastRequestURL, setLastRequestURL] = useState<string>();

  useEffect(() => {
    if (lastRequestURL !== undefined) {
      (async () => {
        try {
          await webRequest(lastRequestURL);
        } catch (e) {
          setResponse(undefined);
        }
      })();
    }
  }, [lastRequestURL]);

 const webRequest = async (value: string) => {
  const response = await axios.get(createURL(`/myServer/website-to-query?url=${encodeURIComponent(value)}`);
  // I do operations server-side with value (a URL) and then send a response back
  if (response) {
    if (newResponse.data.URL &&
              lastRequestURL !== newResponse.data.URL) { // I send the URL back in the data
      return; // This guard check is the key functionality that I want to work. 
      // I check the URL that was used for the request vs. the most recent 
      // URL that a handle change call has received. If it is not the same, 
      // that means that I've don't want to display anything as that 
      // info from the server is already invalid with the front-end's new state
    }
    // Do stuff that is valid for the front-end b/c we passed the check
  }
}

const handleChange = async (value: string): Promise<void> => {
    setLastRequestURL(value);
};

const myFunctionalComponent:React.FC=(
道具:道具
) {
const[lastRequestURL,setLastRequestURL]=useState();
useffect(()=>{
if(lastRequestURL!==未定义){
(异步()=>{
试一试{
等待webRequest(lastRequestURL);
}捕获(e){
setResponse(未定义);
}
})();
}
},[lastRequestURL]);
const webRequest=async(值:string)=>{
const response=wait axios.get(createURL(`/myServer/website to query?url=${encodeURIComponent(value)}`);
//我使用值(URL)在服务器端执行操作,然后返回响应
如果(答复){
如果(newResponse.data.URL)&&
lastRequestURL!==newResponse.data.URL){//我将URL发送回数据中
return;//此保护检查是我想要使用的关键功能。
//我检查用于请求的URL与最近的URL
//句柄更改调用收到的URL。如果不相同,
//这意味着我不想展示这样的东西
//来自服务器的信息已与前端的新状态一起无效
}
//做对前端b/c有效的事情我们通过了检查
}
}
const handleChange=async(值:string):Promise=>{
setLastRequestURL(值);
};

感谢您的帮助。

免责声明:我认为这不是一个好的做法,但如果您真的需要它’\_(ツ)_/当然,您也可以查看axios的请求

您可以使用
ref
来存储可变变量,因此它将独立于生命周期

const myFunctionalComponent: React.FC<Props> = (
  props: Props
) {
  const lastRequestURL = useRef<string>(undefined);

  const webRequest = async (value: string) => {
    const response = await axios.get(createURL(`/myServer/website-to-query?url=${encodeURIComponent(value)}`);
    // I do operations server-side with value (a URL) and then send a response back
    if (response) {
      if (newResponse.data.URL &&
                lastRequestURL.current !== newResponse.data.URL) { // I send the URL back in the data
        return; // This guard check is the key functionality that I want to work. 
        // I check the URL that was used for the request vs. the most recent 
        // URL that a handle change call has received. If it is not the same, 
        // that means that I've don't want to display anything as that 
        // info from the server is already invalid with the front-end's new state
      }
      // Do stuff that is valid for the front-end b/c we passed the check
    }
  }

  const handleChange = async (value: string): Promise<void> => {
    await webRequest(value);
    lastRequestURL.current = value;
  };
}
const myFunctionalComponent:React.FC=(
道具:道具
) {
const lastRequestURL=useRef(未定义);
const webRequest=async(值:string)=>{
const response=wait axios.get(createURL(`/myServer/website to query?url=${encodeURIComponent(value)}`);
//我使用值(URL)在服务器端执行操作,然后返回响应
如果(答复){
如果(newResponse.data.URL)&&
lastRequestURL.current!==newResponse.data.URL){//我将URL发送回数据中
return;//此保护检查是我想要使用的关键功能。
//我检查用于请求的URL与最近的URL
//句柄更改调用收到的URL。如果不相同,
//这意味着我不想展示这样的东西
//来自服务器的信息已与前端的新状态一起无效
}
//做对前端b/c有效的事情我们通过了检查
}
}
const handleChange=async(值:string):Promise=>{
等待webRequest(值);
lastRequestURL.current=值;
};
}

为什么您要直接在webRequest中访问状态?您已经将其作为参数传递了是的,react状态更新是异步的,但它们不是
异步的
函数,您不能等待它们被处理。react状态在渲染周期内被视为常量,其中包括整个
Useeffict
hook callback。它关闭在其中调用的呈现周期中的状态值。@diedu在webRequest使用所需数据解析之前,可以有多个对handleChange的调用。因此,使用URL类似于对多个HTTP请求使用序列号,并抛出来自该请求之前的请求的响应我们已经得到的响应的相应请求。@DrewReese有没有一种方法可以不将webRequest移动到useEffect回调中就可以做到这一点?实际上,我在webRequest中调用了库中的帮助程序,所以我甚至不确定作为最后手段,坏的解决方案是否有效?如果我将其作为类组件,会有帮助吗?会吗什么?你想做什么?我猜在effect hook回调中的某个地方,你正在调用
setLastRequestURL
,并期望
lastRequestURL
在同一个函数中以某种方式更新?@hotzjacobb注意,我删除了
useffect
,因为我认为它是不必要的,如果你保留它,你总是需要一个状态to传递当前url请求和ref以跟踪最后一个url,如果您真的需要它来更新我的回答,请告诉我。谢谢,不,我认为我不需要它。使用useRef会比只使用和变异在我的功能组件之外声明的变量更好吗?@hotzjacobb我添加的链接对此有解释最后是d