Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React with Typescript: why is my array variable an object?

I’m making a simple To-do list application to put into practice what I’m learning, and I’m doing it in Typescript. Literally half an hour ago the application was working fine, but now "all of a sudden" (surely I touched something I shouldn’t have and I’m not realizing what) I can’t apply .map() on my state variable where I store the user’s tasks because in theory it’s an object.

Code of the component where I create my state and define it as an array:

import React, { useState, useEffect } from 'react'
import InputForm from '../InputForm/InputForm'
import ItemsContainer from './ItemsContainer'

export default function Container() {
  const [userTasks, setUserTasks] = useState(
    new Array<{ id: string; name: string; completed: boolean }>()
  )

  // This function is received by <InputForm /> and it returns the new Task.
  // Updates the current tasks (userTasks state) with the new { task } received.
  const addTaskHandler = (task: any) => {
    setUserTasks(task)
  }

  useEffect(() => {
    setUserTasks(JSON.parse(window.localStorage.getItem('Task') || '{}'))
  }, [])

  useEffect(() => {
    window.localStorage.setItem('Task', JSON.stringify(userTasks))
  }, [userTasks])

  return (
    <div className="flex flex-col px-4 container mx-auto sm:max-w-screen-sm">
      {console.log(Array.isArray(userTasks(}
      <InputForm onAddTask={addTaskHandler} />
      <ItemsContainer tasks={userTasks} />
    </div>
  )
}

Code of the component where I do the .map():

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import React from 'react'
import Items from '../Items/Items'

interface Props {
  tasks: Array<{
    id: string
    name: string
    completed: boolean
  }>
}

const ItemsContainer: React.FC<Props> = ({tasks}) => {
  return (
    <ul className='h-96 overflow-auto flex flex-col items-center scrollbar-hide'>
      {tasks.map((task) => (
        <Items name={task.name} key={task.id} />
      ))}
    </ul>
  )
}

export default ItemsContainer

I’m pretty sure that the main cause of this error must be sending me to use Typescript blindly and on the fly, but I would like to leave knowing the error.

Thank you very much in advance!

>Solution :

This is one of the reasons you should avoid using any when using TypeScript. Type things properly, and you’ll be able to see problems during compilation, not during runtime. If you use any, you’re defeating the purpose of using TypeScript.

With

const addTaskHandler = (task: any) => {
    setUserTasks(task)
}

It sounds like task is a singular element of some kind – in which case calling

setUserTasks(task)

will then set the state to that single task – and not an array (which will then mean that calling .map on it will fail).

Figure out type type of a task – it looks like it might be

{ id: string; name: string; completed: boolean }

and type the argument as that, and then append that element to the array in the handler.

type Task = { id: string; name: string; completed: boolean };
const [userTasks, setUserTasks] = useState<Task[]>([]);

const addTaskHandler = (task: Task) => {
    setUserTasks([...userTasks, task]);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading