Reactjs 同时使用多个“useState()”状态

Reactjs 同时使用多个“useState()”状态,reactjs,async-await,react-hooks,Reactjs,Async Await,React Hooks,我正在使用异步API调用获取父记录中的一些模板数据。(子组件将根据在其他子组件中所做的选择进行切换。) 模板数据非常大,所以我只想获取一次。此外,我试图只传递每个孩子所需的最小道具。有些只需要模板的名称,有些则需要适当的组数组。因此,我试图在父元素中完成这项工作。我似乎对设置状态有些困惑 编辑 我正在调用useffect,没有参数,以便它在加载时执行。我希望第一个setTemplates()将设置templatesstate变量,以便我可以在下次调用setTemplateChoices()时使

我正在使用异步API调用获取父记录中的一些模板数据。(子组件将根据在其他子组件中所做的选择进行切换。)

模板数据非常大,所以我只想获取一次。此外,我试图只传递每个孩子所需的最小道具。有些只需要模板的名称,有些则需要适当的组数组。因此,我试图在父元素中完成这项工作。我似乎对设置状态有些困惑


编辑 我正在调用
useffect
,没有参数,以便它在加载时执行。我希望第一个
setTemplates()
将设置
templates
state变量,以便我可以在下次调用
setTemplateChoices()
时使用它,同时设置
templateChoices
状态


我甚至尝试将它们分成两个useEffect调用:

useEffect(() => {
  setTemplates(defaultTemplates)
}, [])

useEffect(() => {
  setTemplateChoices(templates.map(template => template.name))
}, [templates])

还是没有快乐。为什么不设置
模板选项?

将默认设置置于使用状态:

import React, { useState, useEffect } from 'react'

export default function ParentComponent() {
  const [templates, setTemplates] = useState([
    { id: 1, name: 'Form 1', },    // plus - groups: [ {}, {} ... ], etc.
    { id: 2, name: 'Form 2', },    // plus - groups: [ {}, {} ... ], etc.
    { id: 3, name: 'Form 3', },    // plus - groups: [ {}, {} ... ], etc.
  ])
  const [templateChoices, setTemplateChoices] = useState([])



  return (
    <div>
      <h2>Templates</h2>
      {templates.map(template => (
        <p>{template.name}</p>
      ))}
    </div>
  )
}
import React,{useState,useffect}来自“React”
导出默认函数ParentComponent(){
const[templates,setTemplates]=useState([
{id:1,名称:'form1',},//plus-groups:[{},{}…]等。
{id:2,名称:'form2',},//plus-groups:[{},{}…]等。
{id:3,名称:'form3',},//plus-groups:[{},{}…]等。
])
常量[templateChoices,setTemplateChoices]=useState([])
返回(
模板
{templates.map(模板=>(
{template.name}

))} ) }
我假设您正在使用
useffect
,因为您正在从其他地方加载数据,并且由于变量更改,查询中的某些因素可能需要自动刷新

如果没有,您应该直接设置状态(即
useState(defaultQuery)或useState(()=>defaultQuery)
)。这将仅在组件加载时调用它一次

第一个示例不起作用的原因是模板没有立即更新。它需要刷新。您可以使用useEffect两次,但效率很低。更容易的解决办法是

useEffect(() => {
    setTemplates(defaultTemplates);
    setTemplateChoices(defaultTemplates.map(template => template.name));
}, [defaultTemplates]);

对于其他人来说,将它们分成两个useffect调用实际上是可行的:

useEffect(() => {
  setTemplates(defaultTemplates)
}, [])

useEffect(() => {
  setTemplateChoices(templates.map(template => template.name))
}, [templates])

下面是我如何使用React实现这一点的:仅使用1个
useffect
和其中的两个
setState
调用

PS:我没有使用async,因为代码段不太支持它。但是你可以用它

函数mockAPI(){
const defaultTemplates=[
{id:1,名称:'Form 1'},
{id:2,名称:'form2'},
{id:3,名称:'Form 3'},
];
返回新承诺((解决、拒绝)=>{
setTimeout(()=>resolve(defaultTemplates),1000);
});
}
函数App(){
const[templates,setTemplates]=React.useState(null);
const[templateChoices,setTemplateChoices]=React.useState([]);
log(“渲染应用程序…”);
console.log(“模板:”+模板);
log(“templateChoices:+templateChoices”);
React.useffect(()=>{
log(“运行useffect…”);
如果(!模板){
log(“获取模板…”);
mockAPI()。然后((结果)=>setTemplates(结果));
}
否则{
log(“设置模板选项…”);
setTemplateChoices(templates.map(template=>template.name));
}
},[模板];
const choiceItems=templateChoices.map((选项,索引)=>

{choice}

); 返回( 模板? 模板选择? {choiceItems} :null :正在加载模板。。。 ); } render(,document.getElementById(“根”))


您与分离的
useffect()共享的解决方案在我这方面运行良好。
s您需要提供更多信息,您使用两个单独的useffect的第二个解决方案似乎是合理的,应该可以工作-到底什么似乎不起作用?问题是,
setTemplates()
确实似乎在执行useEffect时设置了模板,我不能立即在调用
setTemplateChoices()时使用
templates
state变量(
:-)(我为浪费大家的时间而道歉。一个血淋淋的额头和一张被毁的桌子…后来证明,是的,这两个独立的
useEffect()
呼叫工作得很好-但我发誓,在我尝试呼叫的前4次呼叫中,它们都没有。我现在正在筛选提交,看看我哪里出错了。再次抱歉。
import React, { useState, useEffect } from 'react'

export default function ParentComponent() {
  const [templates, setTemplates] = useState([
    { id: 1, name: 'Form 1', },    // plus - groups: [ {}, {} ... ], etc.
    { id: 2, name: 'Form 2', },    // plus - groups: [ {}, {} ... ], etc.
    { id: 3, name: 'Form 3', },    // plus - groups: [ {}, {} ... ], etc.
  ])
  const [templateChoices, setTemplateChoices] = useState([])



  return (
    <div>
      <h2>Templates</h2>
      {templates.map(template => (
        <p>{template.name}</p>
      ))}
    </div>
  )
}
useEffect(() => {
    setTemplates(defaultTemplates);
    setTemplateChoices(defaultTemplates.map(template => template.name));
}, [defaultTemplates]);
useEffect(() => {
  setTemplates(defaultTemplates)
}, [])

useEffect(() => {
  setTemplateChoices(templates.map(template => template.name))
}, [templates])