【问题标题】:TypeError Cannot read property of undefined even with default values即使使用默认值,TypeError 也无法读取未定义的属性
【发布时间】:2020-12-29 07:10:31
【问题描述】:

当我从我的待办事项列表应用程序中删除列表时,我正在尝试使用默认值,这样每当它尝试获取当前列表信息时,它都会在瞬间使用默认值,直到发布请求刷新可用列表。我已经尝试了所有可能的设置默认值的方法,但是即使我在执行 console.log 语句时,我仍然会收到 TypeError ......这绝对没有意义,因为如果我将“console.log(undefined)”放在它上面,这个语句很好,显然不会导致任何错误,但是下一行会有console.log(myUndefinedStatement),它会导致这个错误。 这是我的代码。 cmets 是默认值的不同选项,我都尝试过但没有一个有效。其中一些 undefined 是一个字符串,但我两种方式都尝试过,只是因为我想不出其他任何东西。此外,对于其中一些人来说,默认值是一个现实的东西,而其他时候它是“hi”,因为我不确定我的其他值是否也可能未定义,所以我尝试了 100% 未定义的东西。

function getCurrentListTitle() {
        // let title = (availableLists[clickedListIndex].title !== "undefined" ?availableLists[clickedListIndex].title : "Hi")
        // return title
        console.log(undefined)
        console.log(availableLists[clickedListIndex].title)
        if (Object.is(availableLists[clickedListIndex].title, undefined)) {
            console.log(availableLists[0].title)
            return availableLists[0].title
        } else {
            console.log(availableLists[clickedListIndex].title)
            return availableLists[clickedListIndex].title
        }
        // return Object.is(availableLists[clickedListIndex].title, undefined) ? console.log("was undefined") : console.log("wasn't undefined");
    }    // ? availableLists[0].title : availableLists[clickedListIndex].title;

这里还有一些代码可能有助于理解我的应用程序

const [lists, setLists] = useState([])


    function deleteList (clickedEl) {
        console.log(lists)
        const delList = {
            name: "please delete",
            listId: clickedEl.id
        }
        if (clickedEl.id) {
            Axios.post("http://localhost:4000/todos/delete", delList)
            .then( () => setLists(delList));
        }
        console.log(lists)
    }

const [availableLists, setAvailableLists] = useState([{title: "", items: ["", "", ""]}]);
    
    useLayoutEffect(() => {
        
        let isMounted = true;
        Axios.get("http://localhost:4000/todos/").then(response => {
          if (isMounted) setAvailableLists(response.data);
        })
        return () => { isMounted = false };
      }, [lists, items]);

更新: 我被要求显示我的函数在哪里被调用或传递,所以这是我的返回语句。函数调用在列表元素中传递。您可能会注意到还有其他 getCurrentList 函数,但我只在函数中包含了一个,因为它们基本上都做同样的事情,只是一个用于标题,一个用于 id,等等。

return(
<div>
    <div className="container">
        <div className="row">
        <Menu 
        onAdd={addList}
        onDelete={deleteList}
        onRename={renameList}
        onChange={changeCurrentList}
        availableLists= {availableLists}
        clickedListIndex= {clickedListIndex}
        />
        <List 
        title={getCurrentListTitle()}
        items={getCurrentListItems()}
        onItemAdd={addItem}
        onItemDelete={deleteItem}
        listId={getCurrentListId()}
        toggleDone={toggleDone}
        />
     </div>
    </div>
</div>
    )

【问题讨论】:

  • 您的代码未显示函数和操作之间的完整相互作用。你在哪里打电话给getCurrentListTitledeleteList?当然console.log(indefined) 是可以的,但是如果你试图读取一个对象的未定义属性就不行了。
  • 如果 availableLists[clickedListIndex].title 抛出 TyperError,这意味着 availableLists[clickedListIndex] 未定义。你需要检查一下。
  • 好的,我更新了帖子以显示我调用函数的位置。另外@terrymorse我知道它是未定义的,因为这就是向我抛出的错误,我只是问它是否未定义,为什么不让我使用默认值或控制台记录它。即使它是未定义的,它也不应该在控制台记录时抛出错误。
  • 代替if (Object.is(availableLists[clickedListIndex].title, undefined)),使用if (typeof availableLists[clickedListIndex] == 'undefined' || Object.is(availableLists[clickedListIndex].title, undefined))。这将防止 TypeError。
  • 从您的 cmets 看来,当没有要显示的列表时,您的问题就会出现。查看
    中元素的结构,在这种情况下,您根本不希望显示 元素,因此也许您应该隐藏该元素直到刷新,而不是尝试显示“默认”列表。

标签: javascript node.js reactjs mongoose


【解决方案1】:
function getCurrentListTitle() {
    
    if ( availableLists[clickedListIndex] ){
        console.log(availableLists[clickedListIndex].title)
        return availableLists[clickedListIndex].title
    } else if ( availableLists[0] ){
        console.log(availableLists[0].title)
        return availableLists[0].title
    };
    // EDIT after OP's comment
    // throw new Error( "No list was found" );
    console.log("No list found");
    return "No list found";
};

或许

function getCurrentListTitle() {
    let title = availableLists[clickedListIndex] ? availableLists[clickedListIndex].title
                : availabileLists[0] ? availableLists[0].title
                // EDIT after OP's comment
                // : null ;
                : "No list found" ;
    console.log( title );
    return title;
};

【讨论】:

  • 这有相同的最终结果。它抛出错误“未找到列表”。所以我的代码仍然无法正常工作:(
  • 嗯 - 在您的原始问题的 cmets 中,您说要显示“默认值”。但是什么是“默认”?我从您的代码中认为您想要显示的默认值是索引 0 处的元素,但如果不是这种情况,那么您需要返回其他内容。因此,您应该返回您想要返回的默认值,而不是抛出错误 - 可能是任何空字符串。或者可能是标题为“未创建列表”。
  • 好吧,这行得通,由于我的应用程序的工作方式,它最终对我来说并不是很好,但就回答我的问题而言,你确实提供了帮助,非常感谢!我最终能够通过从源头修复问题并延迟渲染而不是仅仅尝试设置默认值来避免所有这些。再次感谢
猜你喜欢
  • 2021-12-18
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 2020-05-31
  • 2019-07-05
  • 1970-01-01
  • 1970-01-01
  • 2019-09-17
相关资源
最近更新 更多