refactor: no side effects

This commit is contained in:
cha0s 2020-06-26 05:35:19 -05:00
parent 166ee2dd22
commit 69ec9ef50f

View File

@ -1,8 +1,9 @@
import {mapObject} from '@avocado/core'; import {mapObject} from '@avocado/core';
import {lookupTrait} from '@avocado/entity'; import {lookupTrait} from '@avocado/entity';
import {all as allTraitComponents} from '@avocado/entity/trait/trait-components.scwp'; import {all as allTraitComponents} from '@avocado/entity/trait/trait-components.scwp';
import memoize from 'lodash.memoize';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, {useMemo} from 'react'; import React from 'react';
import {useDispatch} from 'react-redux'; import {useDispatch} from 'react-redux';
import {registerHooks} from 'scwp'; import {registerHooks} from 'scwp';
@ -10,20 +11,24 @@ import Value from '~/client/value';
import {setTraitProperty} from './state'; import {setTraitProperty} from './state';
let TraitComponents; const traitComponents = memoize(() => {
const ensureTraitComponents = () => { return Object.values(allTraitComponents()).reduce((r, M) => {
if (!TraitComponents) {
TraitComponents = Object.values(allTraitComponents()).reduce((r, M) => {
const {default: TraitComponent} = M; const {default: TraitComponent} = M;
return {...r, [TraitComponent.type]: TraitComponent}; return {...r, [TraitComponent.type]: TraitComponent};
}, {}); }, {});
} });
};
const makeTraitPaneRenderer = (context, dispatch, entity, target, traitType) => (trait) => { const TraitPane = (props) => {
ensureTraitComponents(); const {
context,
entity,
target,
trait,
type: traitType,
} = props;
const dispatch = useDispatch();
const {params, state} = trait; const {params, state} = trait;
const {[traitType]: TraitComponent} = TraitComponents; const {[traitType]: TraitComponent} = traitComponents;
const Trait = lookupTrait(traitType); const Trait = lookupTrait(traitType);
if (!Trait) { if (!Trait) {
return null; return null;
@ -67,26 +72,6 @@ const makeTraitPaneRenderer = (context, dispatch, entity, target, traitType) =>
); );
}; };
const TraitPane = (props) => {
const {
context,
entity,
target,
trait,
type,
} = props;
const dispatch = useDispatch();
// TODO: dependency on context is too noisy
const renderTraitPane = useMemo(
() => makeTraitPaneRenderer(context, dispatch, entity, target, type),
[context, dispatch, entity, target, type],
);
return useMemo(
() => renderTraitPane(trait),
[renderTraitPane, trait],
);
};
TraitPane.propTypes = { TraitPane.propTypes = {
context: PropTypes.shape({}).isRequired, context: PropTypes.shape({}).isRequired,
target: PropTypes.string.isRequired, target: PropTypes.string.isRequired,
@ -99,6 +84,9 @@ export default TraitPane;
if (module.hot) { if (module.hot) {
registerHooks({ registerHooks({
autoreg$accept: (type, M) => { autoreg$accept: (type, M) => {
if ('trait-component' === type) {
traitComponents.cache.clear();
}
if ('type-renderer' === type) { if ('type-renderer' === type) {
module.hot.invalidate(); module.hot.invalidate();
} }