【问题标题】:Calling two useState setters in react causes error. Why?在 react 中调用两个 useState 设置器会导致错误。为什么?
【发布时间】:2021-08-05 11:17:27
【问题描述】:

我有这个功能组件:

export const Special = (props) => {
    const [data, setData] = useState();
    const [loading, setLoading] = useState(true);

    const dataRead = (dt) => {
        setData(dt);
        setLoading(false);
    }

    useEffect(() => {
        setLoading(true);
        fetch("/reportTypes/search/visible")
            .then( (response) => response.json() )
            .then( dataRead)            
            .catch( (err) => {
                setLoading(false);
            });
    }, []);

    if ( loading ) return (<Loading />);

    return (        
        <div className="Special">
            <Labeled label="Pricing">
                {JSON.stringify(data)} 
            </Labeled>
        </div>
    );
}

如果我从 dataRead 方法中删除 setData(dt) 或 setLoading(false) 之一,它会起作用。但是,如果两者都存在,则会出现错误:

未捕获的错误:元素类型无效:应为字符串(对于 内置组件)或类/函数(用于复合组件) 但得到:未定义。您可能忘记从 它定义的文件,或者您可能混淆了默认值和命名 进口。

我尝试在没有 useEffect 的情况下调用它 - 结果相同。我用上面的方括号尝试了 useEffect ,没有。我尝试了各种配置。无论如何,但同时调用 setData 和 setLoading 会导致此错误。删除其中一个就可以了。我刚反应过来,所以一定有什么我错过了。

【问题讨论】:

  • 向我们展示您的包含&lt;Loading /&gt; 组件的文件。
  • 你能显示useState的导入吗?
  • 在提问时,重要的是要弄清楚是哪一行实际导致了错误。根据您的问题描述,这可能发生在三个地方:&lt;Loading&gt; 未定义,&lt;Labeled&gt; 未定义,或者您尝试在 data 仍未定义时渲染它,但需要注意的是,错误可能发生在 多个地方取决于当前的代码和条件。

标签: javascript reactjs react-hooks


【解决方案1】:

您尚未指定 setData 使用状态的默认状态值。 const [data, setData] = useState();.

使用 useState 钩子时需要指定默认状态值,就像我们使用时一样。

尝试使用以下代码更改您的 setData 行。在这里,我们将默认状态值指定为空对象。

const [data, setData] = useState({});

【讨论】:

    【解决方案2】:

    我认为无论您在何处使用此特殊组件,您都将其作为简单的导入导入,例如 import Special from 'module',但您并没有将其导出为默认导出,也就是说,您混淆了默认和命名导入,这就是您在此处收到非常清晰的错误消息的原因:

    您可能忘记从定义的文件中导出组件 ,或者你可能混淆了默认和命名的导入。

    尝试将您的命名导出替换为默认导出,如下所示:

    import React from 'react';
    import {useState, useEffect} from 'react';
    
    const App = (props) => {
      const [data, setData] = useState();
      const [loading, setLoading] = useState(true);
    
      const dataRead = (dt) => {
          setData(dt);
          setLoading(false);
      }
    
      useEffect(() => {
          setLoading(true);
          fetch("/reportTypes/search/visible")
              .then( (response) => response.json() )
              .then( dataRead)            
              .catch( (err) => {
                  setLoading(false);
              });
      }, []);
    
      if ( loading ) return (<div>Ankita</div>);
    
      return (        
          <div className="Special">
              <div label="Pricing">
                  <div>Suman</div>
                  {JSON.stringify(data)} 
              </div>
          </div>
      );
    }
    
    export default App;
    

    或者你可以像我们从命名模块导入一样导入。可以使用import { exportName } from 'module' 导入命名模块;

    如需了解默认导出命名导出,请阅读answer

    【讨论】:

      猜你喜欢
      • 2021-12-19
      • 1970-01-01
      • 2019-11-15
      • 2011-11-22
      • 2015-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多