diff --git a/assets/js/src/context/getFeaturesContext.jsx b/assets/js/src/context/getFeaturesContext.jsx deleted file mode 100644 index f947a8a678..0000000000 --- a/assets/js/src/context/getFeaturesContext.jsx +++ /dev/null @@ -1,5 +0,0 @@ -export default function getFeaturesContext(data) { - const flags = data.mailpoet_feature_flags; - const isSupported = (feature) => flags[feature] || false; - return { isSupported }; -} diff --git a/assets/js/src/context/getSegmentsContext.jsx b/assets/js/src/context/getSegmentsContext.jsx deleted file mode 100644 index 401314d9c5..0000000000 --- a/assets/js/src/context/getSegmentsContext.jsx +++ /dev/null @@ -1,5 +0,0 @@ -export default function getSegmentsContext(data) { - return { - all: data.mailpoetSegments, - }; -} diff --git a/assets/js/src/context/getUsersContext.jsx b/assets/js/src/context/getUsersContext.jsx deleted file mode 100644 index af368bc3ab..0000000000 --- a/assets/js/src/context/getUsersContext.jsx +++ /dev/null @@ -1,5 +0,0 @@ -export default function getUsersContext(data) { - return { - isNewUser: data.mailpoet_is_new_user, - }; -} diff --git a/assets/js/src/context/index.jsx b/assets/js/src/context/index.jsx index 3c48722cfe..2066b62abc 100644 --- a/assets/js/src/context/index.jsx +++ b/assets/js/src/context/index.jsx @@ -1,7 +1,7 @@ import React from 'react'; -import getFeaturesContext from './getFeaturesContext.jsx'; -import getSegmentsContext from './getSegmentsContext.jsx'; -import getUsersContext from './getUsersContext.jsx'; +import useFeaturesContext from './useFeaturesContext.jsx'; +import useSegmentsContext from './useSegmentsContext.jsx'; +import useUsersContext from './useUsersContext.jsx'; import useNotices from './useNotices.jsx'; /** @@ -10,9 +10,9 @@ import useNotices from './useNotices.jsx'; * some React hooks to build some parts of the context. */ export function useGlobalContextValue(data) { - const features = getFeaturesContext(data); - const segments = getSegmentsContext(data); - const users = getUsersContext(data); + const features = useFeaturesContext(data); + const segments = useSegmentsContext(data); + const users = useUsersContext(data); const notices = useNotices(); return { features, segments, users, notices, diff --git a/assets/js/src/context/useFeaturesContext.jsx b/assets/js/src/context/useFeaturesContext.jsx new file mode 100644 index 0000000000..d17e856dd4 --- /dev/null +++ b/assets/js/src/context/useFeaturesContext.jsx @@ -0,0 +1,9 @@ +import React from 'react'; + +export default function useFeaturesContext(data) { + return React.useMemo(() => { + const flags = data.mailpoet_feature_flags; + const isSupported = (feature) => flags[feature] || false; + return { isSupported }; + }, [data]); +} diff --git a/assets/js/src/context/useNotices.jsx b/assets/js/src/context/useNotices.jsx index 22caafae2d..4f1c0dfad6 100644 --- a/assets/js/src/context/useNotices.jsx +++ b/assets/js/src/context/useNotices.jsx @@ -4,23 +4,35 @@ export default () => { const [items, setItems] = React.useState([]); const [nextId, setNextId] = React.useState(1); - const getNextId = () => { + const getNextId = React.useCallback(() => { setNextId((x) => x + 1); return nextId; - }; + }, [nextId]); - const add = (item) => { + const add = React.useCallback((item) => { setItems((xs) => [...xs, { ...item, id: item.id || getNextId() }]); - }; + }, [getNextId]); - const remove = (id) => { + const remove = React.useCallback((id) => { setItems((xs) => xs.filter((x) => x.id !== id)); - }; + }, []); - const success = (content, props = {}) => add({ ...props, type: 'success', children: content }); - const info = (content, props = {}) => add({ ...props, type: 'info', children: content }); - const warning = (content, props = {}) => add({ ...props, type: 'warning', children: content }); - const error = (content, props = {}) => add({ ...props, type: 'error', children: content }); + const success = React.useCallback( + (content, props = {}) => add({ ...props, type: 'success', children: content }), + [add] + ); + const info = React.useCallback( + (content, props = {}) => add({ ...props, type: 'info', children: content }), + [add] + ); + const warning = React.useCallback( + (content, props = {}) => add({ ...props, type: 'warning', children: content }), + [add] + ); + const error = React.useCallback( + (content, props = {}) => add({ ...props, type: 'error', children: content }), + [add] + ); return { items, success, info, warning, error, remove, diff --git a/assets/js/src/context/useSegmentsContext.jsx b/assets/js/src/context/useSegmentsContext.jsx new file mode 100644 index 0000000000..c6689e83ae --- /dev/null +++ b/assets/js/src/context/useSegmentsContext.jsx @@ -0,0 +1,7 @@ +import React from 'react'; + +export default function useSegmentsContext(data) { + return React.useMemo(() => ({ + all: data.mailpoetSegments, + }), [data]); +} diff --git a/assets/js/src/context/useUsersContext.jsx b/assets/js/src/context/useUsersContext.jsx new file mode 100644 index 0000000000..9f6f615958 --- /dev/null +++ b/assets/js/src/context/useUsersContext.jsx @@ -0,0 +1,7 @@ +import React from 'react'; + +export default function useUsersContext(data) { + return React.useMemo(() => ({ + isNewUser: data.mailpoet_is_new_user, + }), [data]); +} diff --git a/assets/js/src/experimental_features/experimental_features.jsx b/assets/js/src/experimental_features/experimental_features.jsx index 50c59138e9..2af9d929ea 100644 --- a/assets/js/src/experimental_features/experimental_features.jsx +++ b/assets/js/src/experimental_features/experimental_features.jsx @@ -7,28 +7,25 @@ import Notices from 'notices/notices.jsx'; const ExperimentalFeatures = () => { const [flags, setFlags] = useState(null); const contextValue = useGlobalContextValue(window); - const [mounted, setMounted] = useState(false); + const showError = contextValue.notices.error; useEffect(() => { - if (!mounted) { - MailPoet.Ajax.post({ - api_version: window.mailpoet_api_version, - endpoint: 'featureFlags', - action: 'getAll', - }).done((response) => { - const flagsMap = response.data.reduce((obj, item) => ({ ...obj, [item.name]: item }), {}); - setFlags(flagsMap); - }).fail((response) => { - if (response.errors.length > 0) { - contextValue.notices.error( - <>{response.errors.map((error) =>

{error.message}

)}, - { scroll: true } - ); - } - }); - setMounted(true); - } - }, [contextValue.notices, mounted]); + MailPoet.Ajax.post({ + api_version: window.mailpoet_api_version, + endpoint: 'featureFlags', + action: 'getAll', + }).done((response) => { + const flagsMap = response.data.reduce((obj, item) => ({ ...obj, [item.name]: item }), {}); + setFlags(flagsMap); + }).fail((response) => { + if (response.errors.length > 0) { + showError( + <>{response.errors.map((error) =>

{error.message}

)}, + { scroll: true } + ); + } + }); + }, [showError]); function handleChange(event) { const name = event.target.name; @@ -49,7 +46,7 @@ const ExperimentalFeatures = () => { contextValue.notices.success(

{message}

); }).fail((response) => { if (response.errors.length > 0) { - contextValue.notices.error( + showError( response.errors.map((error) =>

{error.message}

), { scroll: true } );