-1

I'm making it so that every component is one element (button, the whole list, a single element...) I'm having trouble figuring out how to make my list print below the form. Tasks are shown in console.log() but I can't seem to get the right data transferred.

Thanks in advance for any help

This is items.jsx code

import React, { useState} from 'react'
import './todo.css'
import  List from './list'
import Button from './button';

function Items () {
    const [tasks, setTasks] = useState([]);
    const [value, setvalue] = useState("");

    /*  const onChange = (e) => {
        setvalue(e.target.value)
        // console.log('type')
   } */ 

    const onAddTask = (e) =>{
         e.preventDefault();
        console.log('submit')

        const obj = {
            name: value ,
            id: Date.now(),
        };
        if (value !== "") {
            setTasks(tasks.concat(obj));
            setvalue("")
            console.log(obj)
        }
    };
   
    return(
        <div className="form">
            <header>Your todo list</header>
            <input 
                    placeholder="type your task"
                    value={value}
                    onChange={(e) => setvalue(e.target.value)}/>
            <input type="date" placeholder='Set your date!'/>
        <button onClick={onAddTask}>Submit task</button>
        <List data = {List}/>
        </div>
    )
}

export default Items

This is list.jsx code

import React , { useState } from "react";
import  "./Items"
import Button from "./button"

const List = (tasks) => {
    return(
        
        <div>
            {tasks.map}
            
        </div>

    )
    console.log(task.map)
}
export default List
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • 3
    [In order for a question to be answered, it must specify what exactly is wrong. Stating simply that “it doesn’t work” is not sufficient.](https://idownvotedbecau.se/itsnotworking/) – Liam Sep 07 '22 at 13:22
  • Please see [ask], then revise your title to ask a clear, specific question. – isherwood Sep 07 '22 at 13:23
  • 1
    You pass the component to itself as `props.data`, perhaps you mean to send the list of tasks, which you'd then need to either pull from `List`'s parameter (normally called `props`) or destructure it in the parameter declaration. A tutorial covering either JS or React or both might be a good idea. – Dave Newton Sep 07 '22 at 13:27

1 Answers1

0

step 1

Here's a fully functioning demo to get you started -

function Todo() {
  const [items, setItems] = React.useState([])
  const [value, setValue] = React.useState("")
  const addItem = event =>
    setItems([...items, { id: Date.now(), value, done: false }])
  return <div>
    <List items={items} />
    <input value={value} onChange={e => setValue(e.target.value)} />
    <button type="button" onClick={addItem}>Add</button>
  </div>
}

function List({ items = [] }) {
  return <ul>
    {items.map(item =>
      <ListItem key={item.id} item={item} />
    )}
  </ul>
}

function ListItem({ item = {} }) {
  return <li>{item.value}</li>
}    

ReactDOM.render(<Todo />, document.body)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>

start with good state

Note using an Array to store the items is somewhat inefficient for the kinds of operations you will need to perform. Consider using a Map instead. Run the demo again and click on a list item to toggle its state -

const update = (m, key, func) =>
  new Map(m).set(key, func(m.get(key)))

function Todo() {
  const [items, setItems] = React.useState(new Map)
  const [value, setValue] = React.useState("")
  const addItem = event => {
    const id = Date.now()
    setItems(update(items, id, _ => ({ id, value, done: false })))
  }
  const toggleItem = id => event =>
    setItems(update(items, id, item => ({ ...item, done: !item.done })))
  return <div>
    <List items={items} onClick={toggleItem} />
    <input value={value} onChange={e => setValue(e.target.value)} />
    <button type="button" onClick={addItem}>Add</button>
  </div>
}

function List({ items = new Map, onClick }) {
  return <ul>
    {Array.from(items.values(), item =>
      <ListItem key={item.id} item={item} onClick={onClick(item.id)} />
    )}
  </ul>
}

function ListItem({ item = {}, onClick }) {
  return <li onClick={onClick}>
    { item.done
    ? <s>{item.value}</s>
    : item.value
    }
  </li>
}

ReactDOM.render(<Todo />, document.body)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>

do more with less

Functional programming goes a long way in React. Using a curried update function we can take advantage of React's functional updates -

const update = (key, func) => m =>          // <-
  new Map(m).set(key, func(m.get(key)))
function Todo() {
  // ...

  const addItem = event => {
    const id = Date.now()
    setItems(update(id, _ => ({ id, value, done: false }))) // <-
  }
  const toggleItem = id => event =>
    setItems(update(id, item => ({ ...item, done: !item.done }))) // <-
  
  // ...
}

but don't stop there

Avoid creating the todo item data by hand { id: ..., value: ..., done: ... }. Instead let's make an immutable TodoItem class to represent our data. A class also gives us an appropriate container for functions that would operate on our new data type -

class TodoItem {
  constructor(id = 0, value = "", done = false) {
    this.id = id
    this.value = value
    this.done = done
  }
  toggle() {
    return new TodoItem(id, value, !this.done) // <- *new* data
  }
}

Now our Todo component is unmistakable with its intentions -

function Todo() {
  // ...
  const [items, setItems] = useState(new Map)

  const addItem = event => {
    const id = Date.now()
    setItems(update(id, _ => new TodoItem(id, value))) // <- new TodoItem
  }
  const toggleItem = id => event =>
    setItems(update(id, item => item.toggle())) // <- item.toggle
  
  // ...
}
Mulan
  • 129,518
  • 31
  • 228
  • 259