объектами)
и вот у меня возник вопрос
почему например
console.log(tasks)
setTasks(tasks.filter(e => e.id !== this.id));
console.log(tasks)
почему tasks перед setTasks такой же как и после?
setState действия являются асинхронными и группируются для повышения производительности. Это объясняется в документации setState.
а если setState асинхронный, то как я тогда могу сделать например два setState'a. но второй зависящий от первого ?
например вот setTasks(tasks.map((e, i) => { e.done = i === this.id ? !e.done : e.done; return e; })); setCounter({ tasks: tasks.length, done: tasks.filter(e => e.done).length }); ведь не факт, что setCounter нормально посчитает.
Посчитай таски перед setTasks
Зачем хранить отдельно counter, если он всегда вычисляется из другого стейта? Неконсистентненько. Если ты можешь вычислить А из B, то нет никакого смысла держать A в стейте — всегда есть актуальное B, из которого A однозначно вычисляется
да я так для примера чтобы понять что делать с зависимыми стейтами
Зависимые стейты не должны быть стейтом
не ну и нормально так писать? дважды фильтровать tasks. Напрасная работа, мне кажется
Нет, ненормально. Нормальнее вот так const tasks = ... setTasks(...) А ещё нормальнее — не хранить длину массива в стейте — ты вместо state.done всегда можешь взять state.tasks.filter(...).length
А можешь сделать ещё лучше const done = useMemo(() => tasks.filter(...).length, [tasks]) Главное - доку почитай сначала
понял не владею информацией на счёт этого, но гляну
И ради всего святого, не моргай this в функциональных компонентах
да я по bind передал контекст вот и использую или лучше как аргумент передавать?
Лучше как аргумент. Разницы никакой, очевидности больше
onClick={() => props.onDelete(props.task)} или onClick={props.onDelete.bind(null, props.task)}?
Во втором случае всегда будет возращаться новая функция, потому это считай как первый вариант
Bind создаёт так же новую функцию
Обсуждают сегодня