how to create a rendering condition for 3 options? The ternary operator is insufficient for this option and the code I wrote in my opinion is not quite ok.
import React, { useEffect } from "react";
import { useParams } from "react-router-dom";
import { useSelector } from "react-redux";
import { useDispatch } from "react-redux";
import { getTodoItems, setUrlParams } from "../redux/todoSlice";
import TodoItem from "./TodoItem";
const TodoList = ({ filter }) => {
const { id } = useParams();
const dispatch = useDispatch();
const { searchTerm, todoList } = useSelector((state) => state.todo);
useEffect(() => {
dispatch(getTodoItems(id));
dispatch(setUrlParams(+id));
}, [dispatch, id]);
const searchedItems = todoList?.filter((todo) => {
if (!searchTerm) {
return todo;
} else {
return todo?.title.toLowerCase().includes(searchTerm);
}
});
// FROM HERE
const filteredItems = (filter) => {
if (filter === "all") {
return searchedItems?.map((todo, id) => (
<TodoItem key={id} data={todo} />
));
} else if (filter === "active") {
return searchedItems
?.filter((todo) => !todo.isCompleted)
.map((todo, id) => <TodoItem key={id} data={todo} />);
} else if (filter === "done") {
return searchedItems
?.filter((todo) => todo.isCompleted)
.map((todo, id) => <TodoItem key={id} data={todo} />);
}
};
return (
<div>
{filter === "all" && filteredItems("all")}
{filter === "active" && filteredItems("active")}
{filter === "done" && filteredItems("done")}
</div>
);
};
export default TodoList;
Can you please tell me how to make the code more efficient and simpler?
You can use Object literal functionality here. You can define your filteredItems as an object and render them with the type.
const filteredItems = (filter) => {
return {
all: searchedItems?.map((todo, id) => <TodoItem key={id} data={todo} />),
active: searchedItems
?.filter((todo) => !todo.completed)
.map((todo, id) => <TodoItem key={id} data={todo} />),
done: searchedItems
?.filter((todo) => todo.completed)
.map((todo, id) => <TodoItem key={id} data={todo} />),
}[filter];
};
return (
<div>
{filterRender(filter)}
</div>
);
I think that the main problem here is the conditional redundancy, you are doing the same validation two times, I would remove all the if conditions from filteredItems and move each returned TodoItem into his own function, like this:
const TodoList = ({ filter }) => {
const { id } = useParams()
const dispatch = useDispatch()
const { searchTerm, todoList } = useSelector(state => state.todo)
useEffect(() => {
dispatch(getTodoItems(id))
dispatch(setUrlParams(+id))
}, [dispatch, id])
const searchedItems = todoList?.filter(todo => {
if (!searchTerm) {
return todo
} else {
return todo?.title.toLowerCase().includes(searchTerm)
}
})
const AllItems = () => {
return searchedItems?.map((todo, id) => <TodoItem key={id} data={todo} />)
}
const activeItems = () => {
return searchedItems
?.filter(todo => !todo.isCompleted)
.map((todo, id) => <TodoItem key={id} data={todo} />)
}
const doneItems = () => {
return searchedItems
?.filter(todo => todo.isCompleted)
.map((todo, id) => <TodoItem key={id} data={todo} />)
}
return (
<div>
{filter === 'all' && AllItems()}
{filter === 'active' && activeItems()}
{filter === 'done' && doneItems()}
</div>
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With