React 16.8официально запущенHooks
Прошло уже более двух лет, но некоторые друзья всегда считали, что это новая технология, и они не подходят для практического использования.Hooks
все еще в стороне, хотя большинство используютReact
Компании стека технологий, большинство проектов, которые они разрабатывают, используютReact.Component
форма.
Некоторые друзья хотят использоватьReact Hooks
Рефакторинг и модернизация некоторых предприятий или упаковка и оптимизация некоторых общих бизнес-компонентов для повышения масштабируемости проекта, но я не знаю, как это сделать.Hooks
продолжать использоватьMobx
Эта библиотека управления состоянием уже используется, и во время использования она кажется странно пугающей.
Фактически,Mobx
Как самая популярная библиотека управления состоянием на данный момент, она была запущена очень рано.v6версии, идущей в ногу с тенденцией технологии, что значительно облегчает нам вHooks
окружающая среда, тем лучшеReact
Осуществлять управление состоянием. Я думаю, это одна из причин, почему он так популярен!
В этой статье в основном хотят подробно изучить,Mobx
а такжеReact Hooks
Их сочетание может значительно улучшить опыт разработки, а стоимость обучения относительно невелика.
если ты правMobx
а такжеHooks
Если вы заинтересованы и хотите узнать больше и использовать его, то эта статья очень подходит для вас.
Обратите внимание перед чтением:
- Эта статья не будет вводить слишком базовый контент, вам нужно
Mobx
так же какHooks
иметь базовое понимание; - В этой статье будут представлены некоторые рекомендации по сопоставлению приложений, чтобы друзья могли получить более глубокое понимание.
Давайте начнем учиться!
Хуки мощные, зачем вам Mobx?
несомненно,Hooks
очень мощный и, на мой взгляд, особенно великийVue3
в основном относятся кReact Hooks
Хотя между двумя реализациями есть различия, идеи можно использовать для справки. (Только мое личное мнение, надеюсь, вы, ребята, не хотите жаловаться на меня)
Однако в реальном процессе разработки, исключительно используяHooks
Если это так, есть еще некоторые проблемы:
- зависит от заразности- Это приводит к увеличению сложности разработки и снижению ремонтопригодности.
- Кэш Лавина- Это приводит к снижению эксплуатационных характеристик
- Пакетное обновление не может быть выполнено в асинхронных задачах- Это также может привести к снижению производительности
Я не понимаю, что это значит, да? Очень нормально! Позвольте мне объяснить вам снова.
использоватьHooks
При написании кода вы должны знатьuseEffect
а такжеuseCallback
Время изменения «массива зависимостей». иногда твойuseEffect
Опираясь на неизменность функции, неизменность этой функции зависит от неизменности другой функции, образуя таким образом цепочку зависимостей. Как только узел в этой цепочке зависимостей будет случайно изменен, вашuseEffect
был случайно запущен.
Это лучше, чем традиционноеReact.Component
Большее повреждение клеток мозга?
Почему это называется лавиной кеша? Эта проблема в основном вызванаHooks
Функции выполняются независимо, и каждая функция имеет независимую область действия. Переменные функции хранятся в области выполнения, что также можно понимать здесь как замыкание. Данные закрытия создаются каждый раз, и с точки зрения производительности в это время необходимо кэширование. С кэшем будет много проблем. Кроме того, когда у нас есть асинхронные операции, мы часто сталкиваемся с тем, что ссылка на переменную асинхронного обратного вызова является предыдущей, то есть старой, поэтому ее нельзя обновлять пакетами.
фактическиHooks
Эти проблемы вызваны отсутствием общего пространства для обмена данными, вClass
компонент, у нас естьthis
, существуетVue3
, у нас естьsetup作用域
.Hooks
вы можете полагаться только наuseRef + ref.current
Приходитьhack
. Но это крайне неэлегантно и теряет вкус функционального программирования.
Мы программисты со стремлениями, конечно, мы не можем просто так оставить это.
Вы думали о нас в это время?Mobx
, разве это не артефакт, обеспечивающий единую область видимости?
ЭтоHooks
очень мощно, но все же нужноMobx
причина!
API Mobx Dragon Slayer для хуков
Hooks
Существующие проблемы, которые мы только что представили,Mobx
существуетv6Как сохраняются API, представленные в версии?Hooks
Исходя из ее сильных качеств, как вы можете помочь ей решить эти проблемы?
Давайте сначала представим эти два API:
useLocalStore
Mobx
Рекомендуемое использованиеuseLocalStore
организовать состояние компонента. По сути, это более удобный пакет, инкапсулированный в среде Hooks.observable
. Роль состоит в том, чтобы дать ему функцию, и функция возвращает объект, который должен реагировать.
const store = useLocalStore(() => ({key: 'value'}))
это эквивалентно
const [store] = useState(() => observable({key: 'value'}))
Этот API выглядит ничем не примечательным, но он существует, дляHooks
решено依赖传递
а также缓存雪崩
Эта проблема.
Он хранит данные как неизменяемый объект, что может гарантировать, что ссылка на одну и ту же функцию в разное время останется неизменной, и на один и тот же объект или данные можно будет ссылаться в любое время. Нет необходимости вручную добавлять связанныеdeps
. можно избежатьuseCallback
а такжеuseRef
злоупотребление, при обращенииHooks
Приносит закрытие связанных ям.
useObserver
Mobx
Существует три основных способа заставить компонент реагировать на изменения состояния данных:
observer HOC
Observer Component
useObserver hooks
ТрадицияReact.Component
используется вmobx
когда мы используемobserver HOC
Кстати, его основная способность заключается в предоставлении компонентов классаpure component
Возможность, вы можете поставить компоненты классаprops
а такжеstate
Перевести вobservable
state, чтобы реагировать на изменения в состоянии данных.
Точно так же этоHOC
Форма также может находиться непосредственно вHooks
нормальное использование. ноHooks
Не рекомендуетсяHOC
Путь. Так что оказалосьuseObserver
.
import React from 'react';
import { useObserver, useLocalStore } from 'mobx-react';
import {store} from './store';
function Demo1() {
const localStore = useLocalStore(() => store);
return useObserver(() => <div onClick={localStore.setCount}>{localStore.count}</div>)
}
Он кажется очень шелковистым и вернется прямо сейчасNode
использоватьuseObserver
После того, как посылка возвращена, все в порядке.
Такой простой шаг может заставить этот компонент успешно отслеживать изменения данных.Когда данные изменяются, компонент автоматическиre-render
текущий компонент.
оObserver Component
Таким образом, в последней версииMobx
, стал основан наuseObserver
сбываться. также можно комбинироватьHooks
Шелковисто-гладкий в использовании, как и последняя версияMobx
Этот способ более рекомендуется.
import React from 'react';
import { Observer, useLocalStore } from 'mobx-react';
import {store } from './store';
// 更新Observer包裹的位置,注意这里包裹的必须是一个函数
function Demo2() {
const localStore = useLocalStore(() => store);
return <Observer>{() => <span>{localStore.count}</span>}</Observer>
}
Хуки + Mobx = Эффективность
С вышеуказанными двумя API нам нужен только такой шаг, когда мы разрабатываем компонент:
1. Создайте магазин
import { action, observable } from 'mobx';
class Store {
@observable
count = 1;
@action
setCount = () => {
this.count++;
}
}
export const store = new Store();
2. Инжект в магазин, который можно использовать либо в классе, либо в хуках
// 注入store
import { Provider } from 'mobx-react';
import {store} from './store';
function App () {
return (
<Provider store={store}>
<Demo />
</Provider>
)
}
3. Демонстрационное использование
- Как использовать класс
import React, { Component } from 'react';
import { inject, observer } from 'mobx-react';
@inject('scope')
@observer
class Demo1 extends Component {
render() {
return <div>{this.props.count}</div>
}
}
- Как использовать хуки
import React from 'react';
import { useObserver, Observer, useLocalStore } from 'mobx-react';
import {store } from './store';
// 方法1
function Demo1() {
const localStore = useLocalStore(() => store);
return useObserver(() => <div onClick={localStore.setCount}>{localStore.count}</div>)
}
// 方法2
function Demo2() {
const localStore = useLocalStore(() => store);
return <Observer>{() => <span>{localStore.count}</span>}</Observer>
}
На следующих двух примерах вы можете наблюдать,Hooks
СотрудничатьMobx
Шелковистое ощущение:
mobx
Избегается двумя APIuseRef
злоупотреблений.
/**
* 实现一个方法,只有当鼠标移动超过多少像素之后,才会触发组件的更新
*/
// props.size 控制移动多少像素才触发回调
function MouseEventListener(props) {
const [pos, setPos] = useState({x: 0, y: 0})
const posRef = useRef()
const propsRef = useRef()
// 这里需要用 Ref 存储最新的值,保证回调里面用到的一定是最新的值
posRef.current = pos
propsRef.current = propsRef
useEffect(() => {
const handler = (e) => {
const newPos = {x: e.xxx, y: e.xxx}
const oldPos = posRef.current
const size = propsRef.current.size
if (
Math.abs(newPos.x - oldPos.x) >= size
|| Math.abs(newPos.y - oldPos.y) >= size
) {
setPos(newPos)
}
}
// 当组件挂载的时候,注册这个事件
document.addEventListener('mousemove', handler)
return () => document.removeEventListener('mousemove', handler)
}, [])
return (
props.children(pos.x, pos.y)
)
}
// 用 mobx 改写之后,这种使用方式远比原生 hooks 更加符合直觉。
// 不会有任何 ref,任何 current 的使用,任何依赖的变化
function MouseEventListenerMobx(props) {
const state = useLocalStore(target => ({
x: 0,
y: 0,
handler(e) {
const nx = e.xxx
const ny = e.xxx
if (
Math.abs(nx - state.x) >= target.size ||
Math.abs(ny - state.y) >= target.size
) {
state.x = nx
state.y = ny
}
}
}), props)
useEffect(() => {
document.addEventListener('mousemove', state.handler)
return () => document.removeEventListener('mousemove', state.handler)
}, [])
return useObserver(() => props.children(state.x, state.y))
}
Для проблемы пакетного обновления асинхронных данныхmobx
изaction
Эту проблему можно решить очень хорошо.
// 组件挂载之后,拉取数据并重新渲染。不考虑报错的情况
function AppWithHooks() {
const [data, setData] = useState({})
const [loading, setLoading] = useState(true)
useEffect(async () => {
const data = await fetchData()
// 由于在异步回调中,无法触发批量更新,所以会导致 setData 更新一次,setLoading 更新一次
setData(data)
setLoading(false)
}, [])
return (/* ui */)
}
function AppWithMobx() {
const store = useLocalStore(() => ({
data: {},
loading: true,
}))
useEffect(async () => {
const data = await fetchData()
runInAction(() => {
// 这里借助 mobx 的 action,可以很好的做到批量更新,此时组件只会更新一次
store.data = data
store.loading = false
})
}, [])
return useObserver(() => (/* ui */))
}
Что ж, смело добавляйте Mobx+Hooks в свой проект~