React/Taro - Event notification
Event
is an essential part of modern app design, even in micro-app.
Here below is an example of how to use Event
for notifying, i.e. after deletion of a list item, how to notify the list to refresh.
Global data sharing
As mentioned in another article, we have useModel
for global data sharing and operator functions for data manipulating accordingly. So a simple way to "notify" an event is to define an indicator and a toggle
function to change the indicator.
- Define global indicator and function
export default () => {
const [ refresh, { toggle: forceUpdate } ] = useToggle() // from `ahooks`
return {
refresh,
forceUpdate,
}
}
- In List page, add
refresh
as a dependency of the request, something like:
// from `ahooks`
const list = useRequest(() => {
// data request here ...
}, {
refreshDeps: [ refresh, ... ]
})
- In user action, call
forceUpdate
to toggle value ofrefresh
, hence the request will be resent.
// No matter below code is executed in the same page as or different page from list page,
// the list will be refreshed.
handleDelete({...}).then(() => forceUpdate())
Taro.eventCenter
We can use events
from Taro, a handy way is to use Taro.eventCenter directly.
- Define your event & handler, name event to
EVT_DELETE
and handler toforceUpdate
as above - Define a hook name
useEvent
to wrap the logic- Register and Unregister events when enter/exit respectively. A tricky way to avoid repeatedly register
same event & handler is to cancel first then reigster. (off
->on
)
- Register and Unregister events when enter/exit respectively. A tricky way to avoid repeatedly register
- In List page, add
refresh
as a dependency of the request (same as above), something like:
// from `ahooks`
const list = useRequest(() => {
// data request here ...
}, {
refreshDeps: [ refresh, ... ]
})
- In user action, call
forceUpdate
to toggle value ofrefresh
, hence the request will be resent.
// No matter below code is executed in the same page as or different page from list page,
// the list will be refreshed.
handleDelete({...}).then(() => Taro.eventCenter.trigger(EVT_DELETE))
Complete code sample of useEvent
is as below:
export function useEvent(evts?: string[]) {
// eslint-disable-next-line react-hooks/exhaustive-deps
const events = useMemo(() => evts || [], [])
const { refresh, forceUpdate } = useModel('ui')
useEffect(() => {
if (evts) {
console.log('Register for events:', events)
events.forEach(event => {
// Avoid repeatedly registration, first cancel then register
// Same logic as:
// If the event & handler has been registered before, skip it;
// otherwise register the event & handler
Taro.eventCenter.off(event, forceUpdate)
Taro.eventCenter.on(event, forceUpdate)
})
return () => {
console.log('Unregister for events:', events)
events.forEach(event => {
Taro.eventCenter.off(event)
})
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const notifyAdd = useCallback(() => Taro.eventCenter.trigger(EVT_CLIENT_CREATE), [])
const notifyUpdate = useCallback(() => Taro.eventCenter.trigger(EVT_CLIENT_UPDATE), [])
const notifyRemove = useCallback(() => Taro.eventCenter.trigger(EVT_CLIENT_DELETE), [])
return {
refresh,
notifyAdd,
notifyUpdate,
notifyRemove,
}
}
Event
way is a little bit complicated then global data
way, but the good part is that, Event
way is more flexible. It's able to register many events for different purpose, or register one event with many handlers so when one event happened they'll all take actions.
Whatever way you take, pay attention for repeatedly registration. In some cases it might be harmless, but in other cases could cause side effects. For example, if we use register same event & handler several times, and the handler, in our case, is to toggle value of refresh
, so the value of refresh
will be toggled several times hence the list will be refreshed several times, .etc