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

How to push Components to two different divs during mapping in React?

In React I have an array of objects as a state. Let’s say they are "todos". I also have two divs. One div is for incomplete tasks, second is for completed tasks. During mapping I’m using <Todo/> component.

const [todos, setTodos] = useState([
    {id: 1, text: 'Lorem', isComplete: true},
    {id: 2, text: 'Ipsum', isComplete: true}],
    {id: 3, text: 'Test', isComplete: false})
]);

in return I have an HTML structure:

return (     
    <div>
         <h1>Todos</h1>
         <p>My todos for today:</p>
         <div id="incomplete"></div> 
         <p>Todos that've been already done:</p>
         <div id="complete"></div>     
    </div> )

Mapping looks something like this:

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

todos.map(todo => {     
    if(todo.isComplete){
         return <Todo 
                     id={todo.id} 
                     text={todo.text} 
                     isComplete={todo.isComplete}/>         
// AND HERE I WANT TO PUSH THIS COMPONENT INTO div#complete.     
} })

I’m expecting something like this:

return (
     <div>         
         <h1>Todos</h1>
         <p>My todos for today:</p>
         <div id="incomplete">
             <div className="task">
                <p>Test</p>
             </div>
             <div className="task">
                <p>Ipsum</p>
             </div>
         </div>
         <p>Todos that've been already done:</p>
         <div id="complete">
             <div className="task">
                <p>Lorem</p>
             </div>
         </div>
     </div> )

>Solution :

Use filter() before map() to get only the (in)/complete:

return (     
    <div>
         <h1>Todos</h1>
         <p>My todos for today:</p>
         <div id="incomplete">
                {todos.filter(t => !t.isComplete).map(e => <Todo ...{} />)}
         </div> 
         <p>Todos that've been already done:</p>
         <div id="complete">
                {todos.filter(t => t.isComplete).map(e => <Todo ...{} />)}
         </div>     
    </div> 
)

React Demo:

const { useState } = React;

const Todo = (props) => {
    return <p>{props.text}</p>;
}

const Example = () => {

    const [todos, setTodos] = useState([
        {id: 1, text: 'Lorem', isComplete: true},
        {id: 2, text: 'Ipsum', isComplete: true},
        {id: 3, text: 'Test', isComplete: false}
    ]);

    return (     
        <div>
            <h1>Todos</h1>
            <p>My todos for today:</p>
            <div id="incomplete">
                {todos.filter(t => !t.isComplete).map(e => <Todo {...e} />)}
             </div> 
             <p>Todos that've been already done:</p>
             <div id="complete">
                {todos.filter(t => t.isComplete).map(e => <Todo {...e} />)}
             </div>     
        </div> 
    );
}

ReactDOM.render(<Example />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Based on OP’s edit, you can introduce a function like getTodos that will accept a boolean, and create the filter function based on that. Then return <Todo /> accordingly, this will reduce the duplicate filter(), map() and <Todo ... /> so you’ll just need these 2 in the render:

<div id="incomplete">
    {getTodos()}
</div> 
// ....
<div id="complete">
    {getTodos(true)}
</div>   

React Demo:

const { useState } = React;

const Todo = (props) => {
    return <p>{props.text}</p>;
}

const Example = () => {

    const [todos, setTodos] = useState([
        {id: 1, text: 'Lorem', isComplete: true},
        {id: 2, text: 'Ipsum', isComplete: true},
        {id: 3, text: 'Test', isComplete: false}
    ]);
    
    const getTodos = (complete) => {
        const filterFunction = (complete) ? (t => t.isComplete) : (t => !t.isComplete);
        return todos.filter(filterFunction).map(e => {
            return <Todo {...e} />;
        });
    }

    return (     
        <div>
            <h1>Todos</h1>
            <p>My todos for today:</p>
            <div id="incomplete">
                {getTodos()}
             </div> 
             <p>Todos that've been already done:</p>
             <div id="complete">
                {getTodos(true)}
             </div>     
        </div> 
    );
}

ReactDOM.render(<Example />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
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