FilipZafran
FilipZafran

Reputation: 335

Pass multiple data from child to parent in React

I have made a bit more complex To Do list - with a Deadline / Calendar component.

I am able to pass data from the Todo child component to the TodoList Parent, but only the input. I am not able to pass also the Calendar (DeadlineList) data to the parent as well.

PARENT TodoList.js

import React from 'react'; 
import Todo from './Todo';
import DeadlineList from './DeadlineList';

const TodoList = ({ todos, toggleTodo}) => (
    
    <table>
           <tbody>
        <tr>
            <th className='taskTH'>TASK</th>
            <th className='deadlineTH'>DEADLINE</th>
            </tr>
            
            <tr>
            <td className='taskTD'>
                {todos.map(todo => ( 
                    <Todo
                       
                key={todo.id}
                text={todo.text}
                completed={todo.completed}
                toggleTodoItem={() => toggleTodo(todo.id)} />
        )    )}
</td>
            <td
            className="deadlineTd"
            >   {todos.map(todo => ( 

            <DeadlineList
                key={todo.id}
                text={todo.startDate}
                completed={todo.completed}
                onClick={() => toggleTodo(todo.id)} />
        )    )}</td>
        </tr>

   </tbody>
</table>

)

export default TodoList;

CHILD Todo.js - working

import React, { useState } from 'react';
import wooHooSound from '../utils/wooHoo.js'

const Todo = (props) => { 

    const { toggleTodoItem, completed, text } = props;

    let [ shouldPlaySound, setShouldPlaySound ] = useState(true);

    function wooHooEverySecondClick() {
        if (shouldPlaySound) {   
            wooHooSound.play();
            setShouldPlaySound(false);
        } else {
            setShouldPlaySound(true);
        }
    }

    return (
        <li className="bananaLi"
            onClick={() => {
                toggleTodoItem();
                wooHooEverySecondClick();
            }}
            style={{
                textDecoration: completed ? 'line-through' : 'none'
            }}
        > 
            {text}
 
        </li>
    );
};

export default Todo; 

CHILD DeadlineList.js - not passing data

import React from 'react';

const DeadlineList = ({ onClick, completed, value }) => (
    
    
     
    <li className="deadlineLi"
        onClick={onClick}
        style={{
            textDecoration: completed ? 'line-through' : 'none'
        }}
     >
 
       {value}

    </li>
);


export default DeadlineList; 

Upvotes: 1

Views: 3055

Answers (1)

Shubham Verma
Shubham Verma

Reputation: 5054

I see I checked your code there is minor mistake it:

<DeadlineList
                key={todo.id}
                text={todo.startDate}
                completed={todo.completed}
                onClick={() => toggleTodo(todo.id)} />

DeadlineList:

const DeadlineList = ({ onClick, completed, value }) => (
  <li
    className="deadlineLi"
    onClick={onClick}
    style={{
      textDecoration: completed ? "line-through" : "none",
    }}
  >
    {value}
  </li>
);

Mistakes:

  1. In DeadlineList component you are expecting value as a props but in you are not sending from TodoList component
  2. Your todo does not have startDate it has date

Solution:

  1. Update your props in TodoList and DeadlineList
<DeadlineList
                    key={todo.id}
                    value={todo.date}
                    completed={todo.completed}
                    onClick={() => toggleTodo(todo.id)}
                  />

and inside DeadlineList component:

const DeadlineList = ({ onClick, completed, value }) => {
  return (
    <li
      className="deadlineLi"
      onClick={onClick}
      style={{
        textDecoration: completed ? "line-through" : "none"
      }}
    >
      {new Intl.DateTimeFormat("en-US").format(value)}
    </li>
  );
};

Here is your code demo: https://codesandbox.io/s/clever-stonebraker-mpv3r?file=/src/components/DeadlineList.js:28-320

Upvotes: 2

Related Questions