React Hooks:使用useState更新状态不会立即更新状态

时间:2020-01-27 05:17:49

标签: javascript reactjs react-hooks

我有一个包含多个字段的表单,并且其中一个字段包含一个对象数组。

几乎添加了一个对象,该对象包含来自主表单子表单的值。

const addNode = () => {
    let p_form = pForm
    let ha = [vForm, yForm, hForm]
    let info = [....]
    setCurrentNodeForm(
        {
            ...currentNodeForm,
            p: p_form,
            ha: ha,
            info: info,
        }
    )
    // inserts this form to a state called `addedNodes`
    let currArr = [...addedNodes]
    currArr.push(currentNodeForm)
    setAddedNodes(currArr)
    intializeForms()
}

这是我用作onClick按钮的Add功能的功能。

这会将新对象添加到称为addedNodes的状态,该状态是对象的数组。

然后,当我提交主表单时,我将下面的函数用作onClick函数

const submitMainForm = () => {
    let credentials = [...]
    let nodes = [...addedNodes]
    setMainForm(
        {
            ...currentMainForm,
            credentials: credentials,
            nodes: nodes,
        }
    )

    let body = {
        name: .... // something
        objects: currentMainForm,
    }

    intializeForms()

    let options = {
        headers: header,
        method: 'post',
        mode: 'cors',
        body: JSON.stringify(body),
    }

    console.log('options.body', options.body)

    return new Promise((resolve, reject) => {
        fetch(endpoint, options)
            .then(res => res.json())
            .then(resText => {
                console.log('resText', resText)
            })
    }).catch(err => {
        console.log(err)
    })
}

它的作用是,它使用我使用上面的currentMainForm函数更新的当前addedNodes对象数组更新状态addNode。但是,当我如上所述console.log options.body时,objects中的body字段为空。因此,当我发送POST请求时,body缺少了关键部分。

当我在功能之外console.log出现相同内容时,它会显示出来。

我想知道如何保证状态在函数内正确更新。

谢谢。

1 个答案:

答案 0 :(得分:0)

React hook中执行副作用。如果它是功能组件,则在useEffect挂钩中添加api调用。

setMainForm是一个异步函数,因为它具有async的性质,所以您体内没有任何数据。

您可以执行的操作,在Submit函数中更新状态,并使用useEffect钩子监听currentMainForm状态的更改并提交数据。

示例

useEffect( () => {
  fetchData();
}, [currentMainForm]);

const submitMainForm = () => {
  let credentials = [...]
  let nodes = [...addedNodes]
  setMainForm( prevState => {
    return  {
      ...currentMainForm,
      credentials: credentials,
      nodes: nodes,
    }
  });
}

function fetchData() {
  let body = {
    name: '....', // something
    objects: currentMainForm,
  }

  intializeForms()

  let options = {
      headers: header,
      method: 'post',
      mode: 'cors',
      body: JSON.stringify(body),
  }

  console.log('options.body', options.body)

  return new Promise((resolve, reject) => {
      fetch(endpoint, options)
          .then(res => res.json())
          .then(resText => {
              console.log('resText', resText)
          })
  }).catch(err => {
      console.log(err)
  })
}