feat: multiple roots and props
This commit is contained in:
parent
55aaa1cddf
commit
677bc593cc
|
@ -16,10 +16,19 @@ export default {
|
|||
/**
|
||||
* Define root-level React components that are mounted as siblings on `#main`.
|
||||
* Note: `req` will be only be defined when server-side rendering.
|
||||
*
|
||||
* Return either a React component or an array whoe elements must either be a React component
|
||||
* or an array of two elements where the first element is the component and the second element
|
||||
* is the props passed to the component.
|
||||
* @param {http.ClientRequest} req The HTTP request object.
|
||||
*/
|
||||
'@flecks/react.roots': (req) => {
|
||||
// Note that we're not returning `<Component />`, but `Component`.
|
||||
return [
|
||||
Component,
|
||||
[SomeOtherComponent, {prop: 'value'}]
|
||||
];
|
||||
// You can also just:
|
||||
return Component;
|
||||
},
|
||||
},
|
||||
|
|
15
packages/react/src/gather-components.js
Normal file
15
packages/react/src/gather-components.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import React from 'react';
|
||||
|
||||
export default (implementations) => (
|
||||
Object.entries(implementations)
|
||||
.map(([fleck, ComponentOrComponentsOrTuples]) => (
|
||||
[].concat([ComponentOrComponentsOrTuples]).map((ComponentOrTuple, i) => {
|
||||
const key = `${fleck}(${i})`;
|
||||
if (Array.isArray(ComponentOrTuple)) {
|
||||
return React.createElement(ComponentOrTuple[0], {key, ...ComponentOrTuple[1]});
|
||||
}
|
||||
return React.createElement(ComponentOrTuple, {key});
|
||||
})
|
||||
))
|
||||
.flat()
|
||||
);
|
|
@ -9,6 +9,7 @@ export {hot} from 'react-hot-loader';
|
|||
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies, import/no-unresolved
|
||||
export {default as FlecksContext} from '@flecks/react/context';
|
||||
export {default as gatherComponents} from './gather-components';
|
||||
export {default as useEvent} from './hooks/use-event';
|
||||
export {default as useFlecks} from './hooks/use-flecks';
|
||||
export {default as usePrevious} from './hooks/use-previous';
|
||||
|
|
|
@ -4,11 +4,13 @@ import React from 'react';
|
|||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import FlecksContext from '@flecks/react/context';
|
||||
|
||||
import gatherComponents from './gather-components';
|
||||
|
||||
const debug = D('@flecks/react/root');
|
||||
|
||||
export default async (flecks, req) => {
|
||||
const Roots = flecks.invoke('@flecks/react.roots', req);
|
||||
debug('roots: %O', Object.keys(Roots));
|
||||
debug('roots: %O', Roots);
|
||||
const Providers = await flecks.invokeSequentialAsync('@flecks/react.providers', req);
|
||||
const FlattenedProviders = [];
|
||||
for (let i = 0; i < Providers.length; i++) {
|
||||
|
@ -19,21 +21,16 @@ export default async (flecks, req) => {
|
|||
}
|
||||
debug('providers: %O', FlattenedProviders);
|
||||
return () => {
|
||||
const children = Object.entries(Roots)
|
||||
.map(([key, Component]) => React.createElement(Component, {key}));
|
||||
const AllProviders = [
|
||||
[FlecksContext.Provider, {value: flecks}],
|
||||
]
|
||||
.concat(FlattenedProviders);
|
||||
const RootElements = AllProviders
|
||||
.reverse()
|
||||
.reduce((children, [Provider, props], i) => [
|
||||
const RootElements = [[FlecksContext.Provider, {value: flecks}]]
|
||||
.concat(FlattenedProviders)
|
||||
.reduceRight((children, [Provider, props], i) => [
|
||||
React.createElement(
|
||||
Provider,
|
||||
{key: `@flecks/react/provider(${AllProviders.length - (i + 1)})`, ...props},
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
{key: `@flecks/react/provider(${i})`, ...props},
|
||||
children,
|
||||
),
|
||||
], children);
|
||||
], gatherComponents(Roots));
|
||||
return RootElements[0];
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user