【问题标题】:Value is being displayed 2 times and .map function not working - Reactjs值显示 2 次并且 .map 函数不起作用 - Reactjs
【发布时间】:2020-11-16 15:42:05
【问题描述】:
  1. 为什么我的 todo 数据第一次不显示值,但第二次显示,为什么显示 2 次
   const [todos, setTodos] = useState([])
    
    useEffect(() => {
        todolist()
        
    },[])

    const todolist = () => {
        if (typeof window !== undefined) {
            if (localStorage.getItem("jwt")) {
                let temp = JSON.parse(localStorage.getItem("jwt"));
                
                getToDo(temp.user._id, temp.token).then(response => {
                   
                    setTodos(response)
                }).catch((err) => {
                    console.log(err)
                })
            }
        }
    }

    const getToData = () => {
       
        console.log('todo', todos.todos)
      
    }

2.当我应用 .map 函数时,我得到一个错误TypeError: Cannot read property 'map' of undefined

const getToData = () => {
       
        console.log('todo', todos.todos)

        let userTodos = todos.todos
        //here is where i get error
        return userTodos.map((current, index) => {
            return <Todo todo={current} key={index} />
        })
    }

你能帮我解决这两个问题吗

【问题讨论】:

    标签: javascript reactjs react-hooks array.prototype.map


    【解决方案1】:

    useEffect 钩子在你的组件被渲染后被调用。因此,当您的组件第一次渲染时,它将显示空记录,然后调用 useEffect 并且您正在设置 setState 它将触发重新渲染组件(反应默认行为)。

    为了避免错误,您可以获得类似的值

    let userTodos = todos ? todos.todos : []
    

    或通过解构

    let { todos: userTodos = []} = todos;
    

    希望这会对你有所帮助。

    【讨论】:

      【解决方案2】:

      todos 是一个对象,而不是一个数组。因此,您需要将其初始化如下:

      const [todos, setTodos] = useState({})
      

      并且调用端点是异步的,因此在端点调用进行时您将获得空值。因此,您需要设置回退到 todos.todos 以避免 undefined 值如下:

      const userTodos = todos.todos || []
      

      这应该可以解决您的问题。尽情享受吧!

      【讨论】:

        【解决方案3】:

        userTodos.map 位出现错误,因为 userTodostodos.todos,在第一次渲染时是 undefined

        React 正在渲染所有内容,然后运行加载数据的 useEffect,然后使用新状态重新渲染。

        因此您需要处理初始状态,其中todos[],因此您不能在todos.todos 上使用map,因为它不存在。

        有两种方法可以解决这个问题:

        1. 您可以在渲染方法的顶部检查todos.todos === undefined 是否为空,如果"loading..." 为空,则可选择渲染。

        2. 你可以改变你的状态,这样你就没有todo.todos,但待办事项列表直接在根状态列表上,这样你就可以map,但它会在一个空列表上,防止错误.通过在 useEffect 中执行 setTodos(response.todos) 来做到这一点。

        我建议同时执行上述两项操作,因为如果连接速度较慢,用户可以看到正在加载,并且您的状态也将被正确格式化,这样以后出现此类错误的可能性就会降低。

        【讨论】:

          【解决方案4】:

          我了解第二个问题:

          const getToData = () => {
           
             console.log('todo', todos.todos)
          
             let userTodos = todos ? todos.todos : [];
             //here is where i get error
             return userTodos.map((current, index) => {
                return <Todo todo={current} key={index} />
             })
          }
          

          希望它会有所帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-12-04
            • 1970-01-01
            • 2021-01-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多