Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.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 反应:如果一个useState被更新,它怎么能同时不被更新?_Javascript_Reactjs_React Hooks_React State - Fatal编程技术网

Javascript 反应:如果一个useState被更新,它怎么能同时不被更新?

Javascript 反应:如果一个useState被更新,它怎么能同时不被更新?,javascript,reactjs,react-hooks,react-state,Javascript,Reactjs,React Hooks,React State,我有一个反应代码 设置空状态 填充状态 填充此状态后,它会渲染一些图像 然后,该图像触发一个onLoad事件 然后,此onLoad事件调用一个函数,该函数读取初始状态 但此状态为空 这怎么可能?如果调用该函数,则表示状态不再为空 笔 代码 import React,{useRef,useState,useffect}来自“React”; 从“@emotion/styled”导入样式; const useMyHook=(虚拟结构,设置虚拟结构)=>{ useffect(()=>{ log(“虚

我有一个反应代码

  • 设置
    空状态
  • 填充
    状态
  • 填充此状态后,它会渲染一些图像
  • 然后,该图像触发一个
    onLoad
    事件
  • 然后,此onLoad事件调用一个
    函数
    ,该函数读取初始
    状态
  • 但此状态为空
这怎么可能?如果调用该函数,则表示状态不再为空

代码

import React,{useRef,useState,useffect}来自“React”;
从“@emotion/styled”导入样式;
const useMyHook=(虚拟结构,设置虚拟结构)=>{
useffect(()=>{
log(“虚拟_结构已更新!”);
log(虚拟_结构);
log(“虚拟结构已更新!”);
},[virtual_结构];
const refs=useRef([]);
const createStructure=()=>{
log(“虚拟_结构,它是空的吗?”);
log(虚拟_结构);
};
useffect(()=>{
createStructure();
}, []);
常量assignRef=r=>
r&(参考电流包括(r)| |参考电流推动(r));
返回[assignRef,createStructure];
};
导出默认函数App(){
const[virtual_structure,setVirtual_structure]=useState([]);
const[assignRef,updateGrid]=useMyHook(
虚拟_结构,,
SETU结构
);
useffect(()=>{
const temp_structure=Array.from({length:4},()=>({
高度:0,,
单元格:[]
}));
temp_结构[0]。单元格=数组。from({length:10},()=>{
const rand=Math.random();
常数r=rand>0.1?parseInt(500*rand):parseInt(500*0.1);
返回{
高度:“,
el:(
)
};
});
设置虚拟_结构(临时_结构);
}, []);
返回(
{virtual_structure.map((col,i)=>(
{col.cells&&col.cells.map((cell,j)=>{cell.el})
))}
);
}
常量图像=({alt,onload,num,src})=>(
{num}
);
常量Img=styled.Img`
边框:1px实心#000;
高度:最小含量;
保证金:0;
填充:0;
`;
常量标签=styled.div`
位置:绝对位置;
`;
const Container=styled.div`
宽度:100%;
显示:网格;
网格模板柱:1fr 1fr 1fr;
背景:#ccc;
对齐内容:居中对齐;
div{
弹性:1;
div{
颜色:#fff;
字号:700;
字体大小:32px;
保证金:4倍;
}
}
`;
和console.log

virtual_structure is updated!
index.js:27 Array(0)length: 0__proto__: Array(0)
index.js:27 ____virtual_structure is updated!
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure is updated!
index.js:27 Array(4)0: {height: 0, cells: Array(10)}1: {height: 0, cells: Array(0)}2: {height: 0, cells: Array(0)}3: {height: 0, cells: Array(0)}length: 4__proto__: Array(0)
index.js:27 ____virtual_structure is updated!
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 Array(0)length: 0__proto__: Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 []length: 0__proto__: Array(0)
index.js:27 virtual_structure, is it empty?
index.js:27 []
它发生的原因是

您将
updateGrid
函数传递给每个
Image
组件一次,每次装载时
updateGrid

// useEffect closes its lexixal scope upon "updateGrid" 
const [assignRef, updateGrid] = useMyHook(
  virtual_structure,
  setVirtual_structure
);

useEffect(() => {
  ...
  temp_structure[0].cells = Array.from({ length: 10 }, () => {
    return {
      el: (
        <div ref={assignRef}>
//                          v Used inside the callback scope
          <Image onload={updateGrid} />
        </div>
      )
    };
  });

  setVirtual_structure(temp_structure);
}, []);
旁注:永远不要忽略lint警告,尽管您可能知道自己在做什么,但它可能会导致意外的错误


正如@Dennis vash回答中所说,“闭包”冻结了作用域函数中的
useState
变量,因此该函数永远不会看到该变量的当前(更新)值

一种解决方法是,不调用执行逻辑的函数,我总是可以调用更新状态的函数,然后使用此状态触发函数(现在是useEffect而不是函数)


我将把这个问题留待几天讨论,以防有人提出更好的解决方案(?)


代码

import React,{useRef,useState,useffect}来自“React”;
从“@emotion/styled”导入样式;
const useMyHook=(虚拟结构、setVirtual结构、updateGrid)=>{
const refs=useRef([]);
useffect(()=>{
log(“虚拟_结构,它是空的吗?”);
log(虚拟_结构);
},[updateGrid,虚拟_结构];
常量assignRef=r=>
r&(参考电流包括(r)| |参考电流推动(r));
返回[assignRef];
};
导出默认函数App(){
const[virtual_structure,setVirtual_structure]=useState([]);
const[updateGrid,setUpdateGrid]=useState();
const[assignRef]=useMyHook(
虚拟_结构,,
SETU结构,
updateGrid
);
const update=async()=>setUpdateGrid(updateGrid+1);
useffect(()=>{
const temp_structure=Array.from({length:4},()=>({
高度:0,,
单元格:[]
}));
temp_结构[0]。单元格=数组。from({length:10},()=>{
const rand=Math.random();
常数r=rand>0.1?parseInt(500*rand):parseInt(500*0.1);
返回{
高度:“,
el:(
)
};
});
设置虚拟_结构(临时_结构);
}, []);
返回(
{virtual_structure.map((col,i)=>(
{col.cells&&
col.cells.map((cell,j)=>(
{cell.el}
))}
))}
);
}
常量图像=({alt,onload,num,src})=>(
{num}
);
常量Img=styled.Img`
边框:1px实心#000;
高度:最小含量;
保证金:0;
填充:0;
`;
常量标签=styled.div`
位置:绝对位置;
`;
const Container=styled.div`
宽度:100%;
显示:网格;
网格模板柱:1fr 1fr 1fr;
背景:#ccc;
对齐内容:居中对齐;
div{
弹性:1;
div{
颜色:#fff;
字号:700;
字体大小:32px;
保证金:4倍;
}
}
`;

您需要将钩子中使用的所有变量传递到钩子的第二个参数数组中。例如,
useHook(()=>{…},[assignRef,updateGrid,setVirtual_结构]
。如果不这样做,将使您的变量过时,并创建许多其他难以调试的错误。您可以提供一个示例或向我指出一些文档吗?这种语法我认为它是useffect et alit的专有语法,实际上是关于
useffect
。我说了useHooks,以便您也可以
const createStructure = () => {
  console.log('virtual_structure, is it empty?');
  console.log(virtual_structure); // always virtual_structure=[]
};