如何为 3 个选项创建 React 渲染条件
How to create a React render condition for 3 options
如何创建3个选项的渲染条件?三元运算符对于这个选项是不够的,我认为我写的代码不太好。
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;
能否请您告诉我如何使代码更高效、更简单?
我认为这里的主要问题是条件冗余,你做了两次相同的验证,我会从 filteredItems
和将每个返回的 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)
}
})
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>
)
}
您可以在此处使用 Object literal
功能。您可以将 filteredItems
定义为对象并使用类型呈现它们。
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>
);
我可能会做一些像 filter followed by map 这样的事情。
const filteredItems = (filter) => {
let filtered = searchedItems;
if (filter === "active")
filtered = searchedItems
?.filter((todo) => !todo.isCompleted)
if (filter === "done")
filtered = searchedItems
?.filter((todo) => todo.isCompleted)
return filtered.map((todo, id) => <TodoItem key={id} data={todo} />);
};
return (
<div>
{filteredItems(filter)}
</div>
);
如果感觉很糟糕,我可能会更清楚地表明我正在过滤数据集,然后发出一些标记作为结果:
const filteredItems = (filter) => {
if (filter === "active")
return searchedItems
?.filter((todo) => !todo.isCompleted)
if (filter === "done")
return searchedItems
?.filter((todo) => todo.isCompleted)
return searchedItems;
};
return (
<div>
{filteredItems(filter)?.map((todo, id) => <TodoItem key={id} data={todo} />); }
</div>
);
如何创建3个选项的渲染条件?三元运算符对于这个选项是不够的,我认为我写的代码不太好。
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;
能否请您告诉我如何使代码更高效、更简单?
我认为这里的主要问题是条件冗余,你做了两次相同的验证,我会从 filteredItems
和将每个返回的 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)
}
})
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>
)
}
您可以在此处使用 Object literal
功能。您可以将 filteredItems
定义为对象并使用类型呈现它们。
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>
);
我可能会做一些像 filter followed by map 这样的事情。
const filteredItems = (filter) => {
let filtered = searchedItems;
if (filter === "active")
filtered = searchedItems
?.filter((todo) => !todo.isCompleted)
if (filter === "done")
filtered = searchedItems
?.filter((todo) => todo.isCompleted)
return filtered.map((todo, id) => <TodoItem key={id} data={todo} />);
};
return (
<div>
{filteredItems(filter)}
</div>
);
如果感觉很糟糕,我可能会更清楚地表明我正在过滤数据集,然后发出一些标记作为结果:
const filteredItems = (filter) => {
if (filter === "active")
return searchedItems
?.filter((todo) => !todo.isCompleted)
if (filter === "done")
return searchedItems
?.filter((todo) => todo.isCompleted)
return searchedItems;
};
return (
<div>
{filteredItems(filter)?.map((todo, id) => <TodoItem key={id} data={todo} />); }
</div>
);