Комментарии 34
В методе render() не следует изменять состояние компонента (даже с использованием setState), выполнять HTTP-запросы. Не обращайтесь из этого метода к jQuery, не выполняйте запросы на загрузку неких данных.
Кто-то использует React с jQuery???
Говорить, что они уходят в UNSAFE неправильно, ибо их не депрекейтили и пока даже не планируют.
они уже deprecated и будут убраны в 17 версии
Метод render() всегда должен оставаться чистой функцией
Судя по отсутствию аргументов эта функция должна всегда давать один и тот же результат, независимо от стейта.
this — тоже как бы аргумент, и чистые методы вполне могут к нему обращаться.
Только, если этот this будет иммутабельным, что, очевидно, бесполезно.
Эдак надо требовать, чтобы любой переданный в чистую функцию объект был иммутабельным, чего никто обычно не делает.
Обычно всё-таки считается достаточным чтобы функция не изменяла this сама, и возвращала то же самое значение при том условии, что this не изменил никто другой.
чего никто обычно не делает.
И, соответственно, пишет грязные функции. С определением как бы глупо спорить.
Так я и не спорю. Вот только в определении присутствует понятие "одинаковости", которое можно понимать разными способами.
Так вот, если потребовать ссылочной эквивалентности, то окажется что даже простейшая функция вроде x => [x]
не является чистой, из-за чего определение становится практически бесполезным.
А вот если потребовать эквивалентность структурную, то выходит, что мутабельный объект, взятый в разные моменты времени, не является эквивалентным самому себе — а потому совсем не мешает чистоте функции.
А ещё можно пофантазировать о том, что Math.random() — тоже чистая функция, так как между разными вызовами Math — это структурно разные объекты.
Нет, нельзя, потому что Math — пространство имён, а не полноценный объект; у Math нет состояния.
И даже если бы у Math было состояние — Math.random его менял бы.
Давайте зайдём с другой стороны. Вот у нас есть функция render()
:
render() {
return <span>count = {this.state.count}</span>
}
У нас же javascript, и мы её всегда можем вызвать вот так:
render.call(Object.freeze({
state: Object.freeze({
count: 5,
}),
}));
При таком вызове мешает ли что-то считаться функции чистой?
Я вот недавно рассказывал людям, что «теплый ламповый» реакт с классами и методами — это как геоцентрическая вселенная Птолемея с эпициклами, а хуки — это как гелиоцентрическая система Коперника. Известно, что если взять предел по всем эпициклам Птолемея, то результат получится точно таким же, как у Коперника (и совпадет с наблюдаемым миром). Но только коперниковская система неизмеримо проще и логичнее.
Точно так же и с хуками: магическим образом от трети до половины кода просто исчезает при рефакторинге с классов на хуки. Это какой-то очень фундаментальный закон мироздания был открыт.
Так что нет тут никакого «используете ли вы хуки». Есть «весь ли код вы уже перевели на хуки, или пока еще в процессе».
А сколько кода исчезнет при переходе с React на $mol...
Сколько?
Половина так точно.
https://github.com/eigenmethod/todomvc/blob/master/examples/react/js — 10KB
https://github.com/eigenmethod/todomvc/blob/master/examples/mol — 5.5KB
Ну вот взять в пример использование глупого компонента:
<TodoItem
key={todo.id}
todo={todo}
editing={this.state.editing === todo.id}
onToggle={this.toggle.bind(this, todo)}
onDestroy={this.destroy.bind(this, todo)}
onEdit={this.edit.bind(this, todo)}
onSave={this.save.bind(this, todo)}
onCancel={this.cancel}
/>
Аналог на $mol:
Item!id $my_todo_row
todo?val <=> todo!id?val
editing?val <=> todo_editing!id?val
Ну или, что то же самое:
@ $mol_mem
Item( id : string ) {
return $my_todo_row.make({
todo : val => this.todo( id , val ) ,
editing : val => this.todo_editing( id , val ) ,
})
})
Не знаком глубоко с $mol, но выглядит так, будто в react версии есть всякие onSave, onCancel, в $mol версии такого не вижу
Потому что они для реализации той же функциональности не нужны.
Вместо onSave
этот компонент дёргает this.todo({ completed , title })
, а вместо onCancel
— this.editing( false )
.
Благодаря двусторонним каналам API компонента получается гораздо проще, без 100500 колбэков для управления им.
<TodoItem todo={todoGodObject} />
Ваш пример на самом_лучшем_фреймворке ничем не лучше такого подхода.С одной стороны я с вами соглашусь — на хуках код писать удобнее и проще. Но кидаться переписывать рабочий код я бы не стал — мало ли что там пойдёт не так. Работает — и пусть работает.
Уточнение: проста и логична система Кеплера, которая с эллипсами. А у Коперника, при попытках натянуть его систему на реальные наблюдаемые данные, получались всё те же эпициклы.
Анимированное руководство по базовым механизмам React