【问题标题】:Cannot access 'variableName' before initialization初始化前无法访问“variableName”
【发布时间】:2020-09-08 12:31:57
【问题描述】:

当我单击删除按钮时,我想过滤掉该 ID 并重新呈现列表,但我遇到了标题中提到的烦人的错误。

它最终会向服务器发送一个从数据库中删除的请求,但现在我想要的只是要从列表中删除的项目以及在没有该特定记录的情况下再次显示该列表。它基本上是一个包含一堆记录的表。每个旁边都有一个删除按钮。当您单击删除时,它应该删除我正在尝试对 .filter 执行的操作,然后将状态设置为新的 loadedFaq 减去被过滤掉的记录。

按钮:

<Button
  color="purple"
  label="Delete"
  onClick={() => deleteHandler(faq)}
/>

删除处理程序:

  const deleteHandler = async (faq) => {
    const originalFaq = loadedFaq; // loadedFaq is the original state
    const loadedFaq = originalFaq.filter((f) => f._id !== faq._id);
    setLoadedFaq(loadedFaq); // set the state to the original state minus the filtered out record
  };

更新:

它不喜欢我重新声明“loadedFaq”的事实。如果我这样做,它会起作用:

  const deleteHandler = async (faq) => {
    const originalFaq = loadedFaq;
    const loadedFaqTwo = originalFaq.filter((f) => f._id !== faq._id);
    setLoadedFaq(loadedFaqTwo);
  };

【问题讨论】:

  • 您希望在这里发生什么?删除处理程序真的没有意义...您的状态变量是否也称为loadedFaq
  • 能否请您更新问题,以便我们知道您想要做什么?
  • 它最终会向服务器发送一个请求以从数据库中删除,但现在我想要的只是要从列表中删除的项目以及在没有该特定记录的情况下再次显示列表。它基本上是一个包含一堆记录的表。每个旁边都有一个删除按钮。当您单击删除时,它应该删除我正在尝试使用 .filter 执行的项目,然后将状态设置为新的 loadedFaq 减去该记录
  • @AhsanUllah,我已经这样做了。如果需要进一步澄清,请告诉我。
  • @user8463989 数据看起来如何,能否提供该数据或该数据的结构?

标签: reactjs


【解决方案1】:

更简洁的解决方案是根本不使用临时变量:

const deleteHandler = async (faq) => {
  setLoadedFaq(loadedFaq.filter((f) => f._id !== faq._id));
};

这样避免了声明一个新的const同名引起的shadowing问题,更加简洁。

这是导致原始问题的原因的说明:

const {useState} = React;

const Example = () => {
  const [value, setValue] = useState('test');
  
  const myFunction = () => {
    // value comes from the outer scope
    console.log(value);
  }  
  
  const myOtherFunction = () => {
    // value comes from new variable
    const value = 'new!';
    console.log(value);
    // notice it does not modify the state value
    // if you click Test 1 again
  }
  
  const myWrongFunction = () => {
    // value is undefined because we *will* declare it within inner scope
    // even though the outer variable is technically within scope, we cant use it anymore
    console.log(value);
    const value = 'new!';
    
    // value is from new variable
    console.log(value);
  }
   
   return (
    <div>
      <button onClick={() => myFunction()}>Test 1</button>
      <button onClick={() => myOtherFunction()}>Test 2</button>
      <button onClick={() => myWrongFunction()}>Test 3</button>
    </div>
   )
}

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

【讨论】:

  • 啊,我明白了。问题是你们中的两个人给了我完全相同的正确答案,而我不知道该将谁标记为已接受?我将不得不继续技术性,因为布赖恩似乎有正确的哈里斯所做的陈述。对不起,我不知道还能怎么做。如果可以的话,我会接受这两个答案!
  • @user8463989 我用一个导致原始问题的工作示例更新了我的答案。希望这可以为未来解决问题,而不仅仅是现在获得一个可行的解决方案。
  • 感谢 Brian,我非常感谢您付出的额外努力!
【解决方案2】:

loadedFaq 是你的状态,你不应该重新声明它。试试这样的:

const deleteHandler = async (faq) => {
    setLoadedFaq(loadedFaq.filter((f) => f._id !== faq._id)); 
  };

【讨论】:

  • 当然可以。您只是不能声明一个具有相同名称的新变量并且期望它保持与它的外部作用域外部分相同的值。在一个新函数中,它实际上并没有重新声明任何东西。它对状态值没有任何影响。
  • 你是对的。我措辞错误。我应该说“你不应该重新声明它”
猜你喜欢
  • 2020-08-25
  • 2021-09-29
  • 2019-10-12
  • 2020-11-30
  • 2021-11-02
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多