首页 > 解决方案 > state 既没有从 useState 更新,也没有在 useState 中更新 useEffect

问题描述

我面临着与这个问题几乎相同的问题

代码有点太多了,所以我做了一个精简版的问题。(如果我这样做有误,请原谅我

基本上,我有一个主要组件和一个子组件

主要成分

import React {useState} from 'react'
import SubComponent from './subcomponent';

const Main = (props) => {
  const [state, setState] = useState(null);
  const updateStateFunction = (data) => {
    const newState = data
    console.log(state)
    setState(newState)
    console.log(state)
  }

  return (
    <div>
      <SubComponent
        updateStateFunction = {updateStateFunction}
      />
    </div>
  )
}


export default Main;

子组件

import React {useState} from 'react'
const SubComponent = ({updateStateFunction}) => {
  return (
    <div>
      <button
        onClick={() => updateStateFunction("Something new")}
      >       
      </button>
    </div>
  )
}
export default SubComponent;

两个控制台日志都给出了null.

我对解决方案的尝试:

  1. 由于大多数堆栈溢出答案表明使用钩子的状态更新是异步的,我尝试使用setTimeout

  2. 我以为我们可以使用async-await,但这是错误的方法

  3. 我尝试更新内部状态,useEffect但关键是没有任何东西被重新渲染。这是因为正在更新的变量绝不是输出的一部分,而是对辅助变量进行排序以进行进一步的操作。我这样做的方法是使用上述参考问题中的解决方案

const Main = (props) => {

  /*Debugging*/
  let newState = null
  useEffect(()=>{
    console.log("useEffect called")
    setState(newState)
  }, [newState])
  /*Debugging*/

  const [state, setState] = useState(null);
  const updateStateFunction = (data) => {
    newState = data
    console.log(state)
    setState(newState)
    console.log(state)
  }

  return (
    <div>
      <SubComponent
        updateStateFunction = {updateStateFunction}
      />
    </div>
  )
}

我虽然因为 useEffect 钩子甚至没有被执行,所以我没有尝试解决方案中的其他两种方法

我是否引用了错误类型的问题,或者这是反应中的常见行为?

如果需要,很乐意提供更多信息


编辑:
  1. 我之所以添加console.log(),是因为我有操作,然后是使用状态变量值的状态更改。

  2. 使用 React 开发工具,我看到状态正在更新,而且几乎是即时更新的。问题是按钮按下会导致实际代码中的对话框弹出,其组件将该状态用于其他逻辑,因此我收到一个错误,即该状态仍然为空

标签: javascriptreactjsreact-hooksreact-functional-component

解决方案


我不确定let newState = null与引用问题中的任何答案有什么关系,所以要清楚,这是直接应用接受的答案的方式:

const Main = (props) => {
  const [state, setState] = useState(null);
  const updateStateFunction = (data) => { setState(data) }

  useEffect(() => { console.log(state) }, [state])

  return <SubComponent updateStateFunction = {updateStateFunction} />
}

但是,如果状态不用于屏幕上呈现的任何内容,则更改状态是没有意义的 - 如果 Reacts 没有检测到返回值的任何更改,它可能不会将任何更改提交给 DOM 作为优化的一部分,所以在这种情况下,它可能不会运行任何useEffects 。

我建议使用 React Dev Tools 来检查组件的当前状态。

此外,console.log基本上是唯一不需要在里面的副作用useEffect。如果直接在渲染函数中,它将在调用渲染函数时执行,并且不依赖于 React 提交对 DOM 的更改......

请注意,我对引用的问题的回答中的第一个建议不会将 console.log 包装到 useEffect 中 - 再次明确,这是直接应用该建议的方式:

const Main = (props) => {
  const [state, setState] = useState(null);
  const updateStateFunction = (data) => { setState(data) }

  console.log(state)

  return <SubComponent updateStateFunction = {updateStateFunction} />
}

推荐阅读