-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor the Series and Collection data flow (#302)
Simplify a lot of the logic in DataProvider by inverting the source of truth for Series and Collections. This change moves them from immutable props on DataProvider to separate children components which report their configuration (through the DataProvider's Context) into DataProvider's state. This allows DataProvider to be responsible for watching a lot fewer props and move the logic out to the separate components. Additionally, this ensures that the properties for Series and Collection are centrally-documented, due to them using TypeScript for their implementations. This also comes with some nice syntactic sugar around the grouping of Series into Collections (however, this is not required). Another benefit of this cleaned system is that the system can guarantee that Series and Collection objects which leave DataProvider are fully-populated. This will allow us to clean up default props littered throughout the codebase, for things like strokeWidth and color. Finally, in order to ease this massively-breaking API change, a thin backwards-compatibility shim has been introduced into DataProvider. However, this is not intended to be permanent and should be removed before the 0.5.0 stable version is released.
- Loading branch information
Evan Charlton
committed
May 8, 2019
1 parent
389f603
commit 7ca395e
Showing
31 changed files
with
2,133 additions
and
1,838 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import * as React from 'react'; | ||
import Data from '../../context/Data'; | ||
import { ItemProps, WATCHED_PROP_NAMES, Props as SeriesProps } from '../Series'; | ||
import { ItemId } from '../../external'; | ||
import { withDisplayName } from '../../utils/displayName'; | ||
|
||
export interface Props extends ItemProps { | ||
id: ItemId; | ||
} | ||
|
||
type UnregisterCollectionFunction = () => void; | ||
|
||
type RegisterCollectionFunction = ( | ||
collectionProps: Props | ||
) => UnregisterCollectionFunction; | ||
|
||
type UpdateCollectionFunction = (collectionProps: Props) => void; | ||
|
||
interface InternalProps { | ||
registerCollection: RegisterCollectionFunction; | ||
updateCollection: UpdateCollectionFunction; | ||
children?: React.ReactNode[]; | ||
} | ||
|
||
// @ts-ignore - I don't know how to make TypeScript happy about ...props | ||
const Collection: React.FunctionComponent<Props & InternalProps> = ({ | ||
id, | ||
|
||
registerCollection, | ||
updateCollection, | ||
children, | ||
|
||
...props | ||
}) => { | ||
React.useEffect(() => { | ||
return registerCollection({ | ||
id, | ||
...props, | ||
}); | ||
}, []); | ||
|
||
React.useEffect(() => { | ||
return updateCollection({ | ||
id, | ||
...props, | ||
}); | ||
// @ts-ignore - It's okay for props[name] to be implicit any. | ||
}, WATCHED_PROP_NAMES.map(name => props[name])); | ||
|
||
if (React.Children.count(children) === 0) { | ||
return null; | ||
} | ||
|
||
return React.Children.map(children, child => { | ||
if (!child || !React.isValidElement(child)) { | ||
return null; | ||
} | ||
return React.cloneElement(child as React.ReactElement<SeriesProps>, { | ||
...child.props, | ||
collectionId: id, | ||
}); | ||
}); | ||
}; | ||
|
||
export default withDisplayName( | ||
'Collection', | ||
(props: Props & { children: React.ReactNode[] }) => ( | ||
<Data.Consumer> | ||
{({ registerCollection, updateCollection }: InternalProps) => ( | ||
<Collection | ||
registerCollection={registerCollection} | ||
updateCollection={updateCollection} | ||
{...props} | ||
> | ||
{props.children} | ||
</Collection> | ||
)} | ||
</Data.Consumer> | ||
) | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.