![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
extended-components
Advanced tools
Extend functional React.js components with default props, advanced local state (presets for common use cases like toggle, counter, ...) and lifecycle hooks.
Extend functional React.js components with default props, advanced local state (presets for common use cases like toggle, counter, ...) and lifecycle hooks.
This package is not meant as a replacement for state management libraries like Redux, it should be used for local state only (i.e. state that is used by not really more than one component).
There are two problems that motivated me to create this package:
This package consists of some higher order components (HOC), which let you define default props, state and lifecycle methods for a functional component. Also you can define state presets like useCounterState
or useToggleState
that can be used with the withState
HOC perfectly. If you define state, extended-components
will pass a second argument to your functional component (as described by Andrew Clark).
This package uses HOCs and not render props. Don't get me wrong, I use render props a lot, but I think in this case HOCs have slightly advantages like a good separation of concerns and clean code.
Technically extended-components
makes use of component squashing, so the original functional component will be squashed by the HOCs to improve performance.
npm install extended-components
# or
yarn add extended-components
import React from 'react';
import { compose, withState, lifecycle, pure } from 'extended-components';
import useCounterState from './useCounterState';
const enhance = compose(
// Use state helpers to define state
withState({
counter: useCounterState(),
}),
// Use React.js lifecycle hooks with props and state
lifecycle((props, { counter }) => {
componentDidUpdate() {
counter.increment();
},
}),
// Component is a pure component
pure(),
});
// Use defined state
function Component(props, state) {
const { counter } = state;
return (
<div>
<p>This component was updated {counter.count} times.</p>
<p>
<button onClick={() => { counter.reset() }}>Reset counter</button>
</p>
</div>
);
}
export default enhance(Component);
Hint: You can use the HOCs of extended-components
in conjunction with other higher order components, but thus these higher order components don't expect a functional component with two arguments, HOCs of extended-components
should always be placed last, e.g.:
const enhance = compose(
withRouter(...),
connect(...),
graphql(...),
mapProps(...),
// Use extended-components HOCs last
withState(...),
);
The purpose of this package is to enable a convient way to define state for specific use cases, but not to implement all these use cases. So it is up to you to define state helpers. A state helper is simply an object with the keys initial
(for initial state) and mutators
(for state mutator functions):
function useCounterState() {
return {
initial: {
count: 0
},
mutators: setState => ({
increment: () => {
setState(({ count }) => ({ count: count + 1 }));
},
decrement: () => {
setState(({ count }) => ({ count: count - 1 }));
},
reset: () => {
setState({ count: 0 });
}
})
};
}
Then you can reuse this state helper over and over like shown in the example above. For more examples have a look at the examples
folder.
defaultProps
Defines the default props of a component.
type DefaultProps = ((defaultProps: $Shape<Props>) => void) => HOC
getDerivedStateFromProps
Defines the static lifecycle hook getDerivedStateFromProps
(introduced in React 16.3). Notice that this hook returns void (in comparison to the original hook, which returns a state object), because you can update the state via the state mutators.
type GetDerivedStateFromProps = ((nextProps: Props, prevState?: State) => void) => HOC
lifecycle
Defines lifecycle hooks.
type Lifecycle = (
(
props: Props,
state?: State,
) => {
componentDidMount?: () => void,
shouldComponentUpdate?: (nextProps: Props, nextState?: State) => boolean,
componentDidUpdate?: (prevProps: Props, prevState?: State) => void,
componentWillUnmount?: () => void,
},
) => HOC;
pure
Equivalent to React.PureComponent
, but instead of a basic shallow state comparison this function makes a shallow comparison for the state of every state helper.
type Pure = () => HOC;
withState
Defines state with state helpers.
type WithState = ({
[string]: StateHelper<SubStateValues, SubStateMutators, Props>,
}) => HOC;
statics
Defines static properties of a component.
type Statics = Object => HOC;
As stated above you can define your own state helpers that should be of the following type:
type SetState<SubStateValues, Props> = (
$Shape<SubStateValues> | ((SubStateValues, Props) => $Shape<SubStateValues>),
) => void;
type StateHelper<SubStateValues, SubStateMutators, Props> = {
initial: SubStateValues,
mutators: (SetState<SubStateValues, Props>) => SubStateMutators,
};
The definitions above might differ from the real Flow definitions, because the definitions in this section should just demonstrate what you can do with this package.
For more information about the usage with Flow see Flow support.
This package is heavily inspired by Andrew Clark's great library recompose
. And I think you can perfectly use recompose
and extended-components
together, because extended-components
just mimics all class features and recompose
offers a lot more utils. You can use extended-components
for state and lifecycle hooks and recompose
for props manipulation and more.
Currently there are only two arguments that are passed to a functional component, but you can think of more arguments. So it might be that someday this package will offer an api for higher order components like withTheme
, withIntl
, withRouter
and so on, which add more arguments to the component. Each argument for a specific use case.
This package is released under the MIT License.
FAQs
Extend functional React.js components with default props, advanced local state (presets for common use cases like toggle, counter, ...) and lifecycle hooks.
The npm package extended-components receives a total of 3 weekly downloads. As such, extended-components popularity was classified as not popular.
We found that extended-components demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.