React useState 似乎在这里不接受默认值?

Posted

技术标签:

【中文标题】React useState 似乎在这里不接受默认值?【英文标题】:React useState does not seem to accept a default value here? 【发布时间】:2019-11-05 23:57:15 【问题描述】:

我有一个图表组件,可以在其中显示/隐藏特定的线条。为了跟踪哪些行处于活动状态,我将activeKeys 数组保持在一个状态。最初,我从获取数据数组的函数getKeys 中获取键名。

当我这样做时:

    const defaultValue = getKeys(data)
    console.log('defaultValue from keys', defaultValue)
    const [activeKeys, setActiveKeys] = useState(defaultValue)
    console.log('activeKeys', activeKeys)

第一个控制台日志显示正确的键:

["createdCount", "confirmedCount", "hasFeedbackCount"]

第二个控制台日志显示[]

但是如果我这样做:

const defaultValue = ["createdCount", "confirmedCount","hasFeedbackCount"]
console.log('defaultValue', defaultValue)
const [activeKeys, setActiveKeys] = useState(defaultValue)
console.log('activeKeys', activeKeys)

第一个控制台日志显示相同的数组:

["createdCount", "confirmedCount", "hasFeedbackCount"]

并且 activeKeys 显示正确的数组:

["createdCount", "confirmedCount", "hasFeedbackCount"]

useState 坏了还是什么? getKeys 是一个简单的函数,没有承诺或类似的东西。它看起来像这样:

const getKeys = (data: Props['data']): string[] => 
  const reduced = data.reduce((acc, datum) => [...acc, ...Object.keys(datum.lines)] as any, [])
  const setted = new Set(reduced)
  const arrayed = Array.from(setted)
  return arrayed

Props['data']的形状是:

  data: 
    date: string
    lines: Partial<Record<string, number>>
  []

【问题讨论】:

什么是def?不应该是defaultValue吗? @tkausl 你真快!我现在编辑了它,它只是一个错字。在我的代码中,我写了所有def,但我在这里发布了我想通过将其重命名为defaultValue 我无法在 codesandbox.io/s/react-typescript-763kf 复制此内容。你能分享一个重现问题的沙盒吗? 尝试打印数据以及默认值数组 @MehdiSaffar 你解决了这个问题吗? 【参考方案1】:

我遇到了同样的问题。 React.useState没有bug是对的。

这里的问题是您的组件正在被挂载并将空数组计算为默认值。随后,您的“默认值”将更改为您的预期默认值,但 React.useState 已经有一个空数组的默认值。

要解决此问题,您需要避免安装组件,直到所需的默认值可用。或者,您也可以使用React.useEffect 挂钩来查找道具的变化并调用React.useState 输出的设置器(数组中的第二项)。

【讨论】:

【参考方案2】:

useState 似乎没有问题。

根据React DOCs:

我们将什么作为参数传递给 useState?

useState() Hook 的唯一参数是初始状态。 与类不同,状态不必是对象。如果需要的话,我们可以保留一个数字或字符串。 在我们的示例中,我们只需要一个数字来表示用户点击了多少次,因此将 0 作为变量的初始状态传递。 (如果我们想在 state 中存储两个不同的值,我们会调用 useState() 两次。)

因此,将字符串数组作为useState 的初始状态传递是完全正常的。即使它是函数的结果。 (参见下面的 sn-p)。

我无法在 SO Snippet Editor 上重现您的 getKeys 函数,我建议您进一步检查。虽然这也可能是 sn-p 构建器可能不支持某些 JS 功能的问题。

注意:这不是useState 的问题。还有其他事情出错了。尝试提交正在重现的问题的工作示例。

function App() 
  
  const someFunction = (x) => 
    return x;
  
  
  const data = ['A','B','C'];
  
  const [state,setState] = React.useState(someFunction(data));
  
  console.log(state);
  
  return(
    <div>state.toString()</div>
  );


ReactDOM.render(<App/>,document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>

【讨论】:

【参考方案3】:

您将 def 而不是 defaultValue 传递给 useState();

const defaultValue = getKeys(data)
console.log('defaultValue from keys', defaultValue)
const [activeKeys, setActiveKeys] = useState(defaultValue)
console.log('activeKeys', activeKeys)

【讨论】:

很抱歉,这是错字。在我的代码中,我写了def,但我想将其更改为defaultValue,以便在发布到 *** 时更清楚。我编辑了我的帖子。

以上是关于React useState 似乎在这里不接受默认值?的主要内容,如果未能解决你的问题,请参考以下文章

[react] 请说说什么是useState?为什么要使用useState?

ZF_react hooks useState的实现 useCallback useMemo useReducer useContext

useEffect 中的 useState 不更新状态

Firebase 和 React Hooks(useState 和 useEffect)

useState 变量不是删除函数中的最新版本,React

react usestate 重新设置数据后,不渲染页面