Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/382.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 反应-更新状态数组 上下文_Javascript_Arrays_Reactjs_Object_React Hooks - Fatal编程技术网

Javascript 反应-更新状态数组 上下文

Javascript 反应-更新状态数组 上下文,javascript,arrays,reactjs,object,react-hooks,Javascript,Arrays,Reactjs,Object,React Hooks,嗨 我正在创建一个表单来创建虚拟机。信息跨多个页面(组件)收集,并集中在顶级组件中 它的状态对象如下所示: const[vmProp,setVmProp]=useState({ 姓名:“, 图像_id:“”, 图像名称:“”, 卷列表:[], RAM:“, vcpu:“”, 自动启动:对, }); 问题 我希望能够将卷添加/删除到卷列表中,并且我希望卷列表如下所示: [ { 名称:“主要”, 尺寸:1024 }, { 名称:“备份”, 尺寸:2048 }, { 名称:“出口”, 尺寸:2048

我正在创建一个表单来创建虚拟机。信息跨多个页面(组件)收集,并集中在顶级组件中

它的状态对象如下所示:

const[vmProp,setVmProp]=useState({
姓名:“,
图像_id:“”,
图像名称:“”,
卷列表:[],
RAM:“,
vcpu:“”,
自动启动:对,
});
问题 我希望能够将卷添加/删除到卷列表中,并且我希望卷列表如下所示:

[
{
名称:“主要”,
尺寸:1024
},
{
名称:“备份”,
尺寸:2048
},
{
名称:“出口”,
尺寸:2048
}
]
我试过的 现在我只尝试添加一个卷

1:工作,但不生产我想要的
const handleAddVolume=(obj)=>{
setVmProp({…vmProp,
卷列表:{
…vmProp.volumesList,
[对象名称]:{
尺寸:obj.size,
},
} });
};
它正在工作,但输出为:

[
姓名:{
尺寸:1024
}
]
2:应该可以,但是不行
const handleAddVolume=(obj)=>{
setVmProp({…vmProp,
卷列表:{
…vmProp.volumesList,
{
名称:obj.name,
尺寸:obj.size,
},
} });
};
输出:

[
名称:“主要”,
尺寸:1024
]
你对如何处理这种状态对象有什么想法吗?
谢谢

如果您不需要从其他状态嵌套/取消测试卷列表,您会过得更好。(更惯用的做法是为这些值中的每一个都有一个状态原子,但对于布尔值和字符串等简单值,就可以了。)


如果不需要从另一个状态嵌套/取消嵌套卷列表,您将有一个更好的时间。(更惯用的做法是为这些值中的每一个都有一个状态原子,但对于布尔值和字符串等简单值,就可以了。)


volumesList不应是对象,将其作为HandLeadVolume函数中的数组

试试下面的方法

const handleAddVolume = (obj) => {
    setVmProp({ ...vmProp,
        volumesList: [
            ...vmProp.volumesList,
            {
                name: obj.name,
                size: obj.size,
            }
        ] });
};

volumesList不应是对象,将其作为HandLeadVolume函数中的数组

试试下面的方法

const handleAddVolume = (obj) => {
    setVmProp({ ...vmProp,
        volumesList: [
            ...vmProp.volumesList,
            {
                name: obj.name,
                size: obj.size,
            }
        ] });
};

以下是一个工作示例:

const Example = (props) => {
  const inputRef = createRef();
  const [vmProp, setVmProp] = useState({
    name: "",
    image_id: "",
    image_name: "",
    volumesList: [],
    RAM: "",
    vcpu: "",
    autostart: true,
  });

  const { volumesList } = vmProp;

  const handleAddVolume = (e) => {
    e.preventDefault();
    const input = inputRef.current.value;
    setVmProp((prevVmProp) => {
      const newVmProp = { ...prevVmProp };
      newVmProp.volumesList.push({
        name: input,
        size: 1024,
      });
      return newVmProp;
    });
    // reset the input
    inputRef.current.value = "";
  };

  return (
    <>
      <form>
        <input ref={inputRef} type="text" />
        <button onClick={handleAddVolume}>Add volume</button>
      </form>
      {volumesList.map((volume) => (
        <div key={volume.name}>{`${volume.name} - ${volume.size}`}</div>
      ))}
    </>
  );
};

export default Example;
const示例=(道具)=>{
const inputRef=createRef();
常量[vmProp,setVmProp]=useState({
姓名:“,
图像_id:“”,
图像名称:“”,
卷列表:[],
RAM:“,
vcpu:“”,
自动启动:对,
});
const{volumesList}=vmProp;
常数handleAddVolume=(e)=>{
e、 预防默认值();
常量输入=inputRef.current.value;
setVmProp((prevVmProp)=>{
const newVmProp={…prevVmProp};
newVmProp.volumesList.push({
名称:输入,
大小:1024,
});
返回newVmProp;
});
//重置输入
inputRef.current.value=“”;
};
返回(
增加音量
{volumesList.map((卷)=>(
{`${volume.name}-${volume.size}`}
))}
);
};
导出默认示例;

这只是一个概念的证明。基本上,
setVmProp
接受一个函数,该函数在更新为asynchornus时获取最新状态值,并返回状态的新值。因此,使用函数,我复制了名为
newVmProp
vmProp
的最新值,然后将一个新对象推送到
newVmProp.volumesList
中,然后返回包含新添加的卷和其他所有内容的
newVmProp
。我从输入字段获得的
名称的值。同样,这只是一个概念证明。

以下是一个工作示例:

const Example = (props) => {
  const inputRef = createRef();
  const [vmProp, setVmProp] = useState({
    name: "",
    image_id: "",
    image_name: "",
    volumesList: [],
    RAM: "",
    vcpu: "",
    autostart: true,
  });

  const { volumesList } = vmProp;

  const handleAddVolume = (e) => {
    e.preventDefault();
    const input = inputRef.current.value;
    setVmProp((prevVmProp) => {
      const newVmProp = { ...prevVmProp };
      newVmProp.volumesList.push({
        name: input,
        size: 1024,
      });
      return newVmProp;
    });
    // reset the input
    inputRef.current.value = "";
  };

  return (
    <>
      <form>
        <input ref={inputRef} type="text" />
        <button onClick={handleAddVolume}>Add volume</button>
      </form>
      {volumesList.map((volume) => (
        <div key={volume.name}>{`${volume.name} - ${volume.size}`}</div>
      ))}
    </>
  );
};

export default Example;
const示例=(道具)=>{
const inputRef=createRef();
常量[vmProp,setVmProp]=useState({
姓名:“,
图像_id:“”,
图像名称:“”,
卷列表:[],
RAM:“,
vcpu:“”,
自动启动:对,
});
const{volumesList}=vmProp;
常数handleAddVolume=(e)=>{
e、 预防默认值();
常量输入=inputRef.current.value;
setVmProp((prevVmProp)=>{
const newVmProp={…prevVmProp};
newVmProp.volumesList.push({
名称:输入,
大小:1024,
});
返回newVmProp;
});
//重置输入
inputRef.current.value=“”;
};
返回(
增加音量
{volumesList.map((卷)=>(
{`${volume.name}-${volume.size}`}
))}
);
};
导出默认示例;

这只是一个概念的证明。基本上,
setVmProp
接受一个函数,该函数在更新为asynchornus时获取最新状态值,并返回状态的新值。因此,使用函数,我复制了名为
newVmProp
vmProp
的最新值,然后将一个新对象推送到
newVmProp.volumesList
中,然后返回包含新添加的卷和其他所有内容的
newVmProp
。我从输入字段获得的
名称的值。同样,这只是一个概念证明。

由于我需要能够在数组中添加/删除/替换对象,我决定创建它自己的状态,如下所示:


常量[volumesList,setVolumesList]=useState([]);
const handleAddVolume=(obj)=>{
setVolumesList((oldList)=>[…oldList,obj]);
};
常量HandlerRemoveVolume=(obj)=>{
setVolumesList((oldList)=>oldList.filter((item)=>item.name!==obj.name));
};
常量handleEditVolume=(obj)=>{
设置卷列表(
volumesList.map((卷)=>
(volume.name==obj.name
?{…卷,…obj}
:体积),
),
);
};

谢谢你的回答

由于我需要能够在数组中添加/删除/替换对象,我决定创建它自己的状态,如下所示:


常数[