Note: I've seen people suggesting useEffect to this issue but I am not updating the state through useEffect here..
The problem I am having is that when a user selects id 7 for example, it triggers a function in App.tsx and filters the todo list data and update the state with the filtered list. But in the browser, it doesn't reflect the updated state immediately. It renders one step behind.
Here is a Demo
How do I fix this issue (without combining App.tsx and TodoSelect.tsx) ?
function App() {
const [todoData, setTodoData] = useState<Todo[]>([]);
const [filteredTodoList, setFilteredTodoList] = useState<Todo[]>([]);
const [selectedTodoUser, setSelectedTodoUser] = useState<string | null>(null);
const filterTodos = () => {
let filteredTodos = todoData.filter(
(todo) => todo.userId.toString() === selectedTodoUser
);
setFilteredTodoList(filteredTodos);
};
useEffect(() => {
const getTodoData = async () => {
console.log("useeffect");
try {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/todos"
);
setTodoData(response.data);
setFilteredTodoList(response.data);
} catch (error) {
console.log(error);
}
};
getTodoData();
}, []);
const handleSelect = (todoUser: string) => {
setSelectedTodoUser(todoUser);
filterTodos();
};
return (
<div className="main">
<TodoSelect onSelect={handleSelect} />
<h1>Todo List</h1>
<div>
{" "}
{filteredTodoList.map((todo) => (
<div>
<div>User: {todo.userId}</div>
<div>Title: {todo.title}</div>
</div>
))}
</div>
</div>
);
}
In TodoSelect.tsx
export default function TodoSelect({ onSelect }: TodoUsers) {
const users = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
return (
<div>
<span>User: </span>
<select
onChange={(e) => {
onSelect(e.target.value);
}}
>
{users.map((item) => (
<option value={item} key={item}>
{item}
</option>
))}
</select>
</div>
);
}