React Partial
Do you prefer writing stateless function components (introduced with React 0.14) over class syntax but still occasionally need lifecycle methods or state?
React Partial lets you keep writing stateless components by giving you lifted component methods which can be used to create partial, higher order components. These partial components are used to wrap your existing components, giving them new functionality in a declarative, functional manner.
The purpose of the library is to allow you to start with stateless functions as your go-to component and wrap them with stateful components when needed. This is not only helpful if you prefer writing stateless UI components but can also help you to find reusable patterns with your stateful containers. By abstracting stateful logic in containers, it becomes easy to add functionality to existing UI components and write simpler code. More on examples of reusable containers here.
React Partial is lightweight, just around ~10KB.
const didMount = self //state gets merged to stateless component's propsconst Component = <h1>propsmessage</h1> didMount Component
const Hello = <h1>Hello propsworld propssmiley</h1> //combine functionality with ease Hello
Installing
npm:
npm install react-partial
Supported methods
React Partial supports all the specifications of React.createClass():
Specs: getInitialState, getDefaultProps, propTypes, mixins, statics, displayName
Lifecycle methods: componentWillMount, componentDidMount, componentWillReceiveProps, shouldComponentUpdate, componentWillUpdate, componentDidUpdate, componentWillUnmount
How component methods work
Every component method in React Partial follows the same pattern:
//etc...
- The first argument is always the value which the method expects, eg. propTypes takes an object, componentDidMount takes a function.
- Each function's arguments get prepended with
this
and appended withthis.props, this.state
:
componentDidMount((self, props, state) => ...)
shouldComponentUpdate((self, nextProps, nextState, props, state) => ...)
- The reasoning for the order is that
this
is often necessary whileprops
andstate
are just there for convenience, eg. if you want to destructure arguments.
- The reasoning for the order is that
- Each function's arguments get prepended with
- Second argument is optional, and when omitted a new curried function is returned which takes a single argument
componentMethod/Component
- If componentMethod is given, its functionality is added to the existing method(s) and a new curried function is returned which takes a single argument
Component/componentMethod
- If Component is given, a new React component is returned. The returned component wraps Component with a higher order component with all the given partial methods.
- If componentMethod is given, its functionality is added to the existing method(s) and a new curried function is returned which takes a single argument
Utility functions
combine(...funcs)
Combines multiple component methods without having to write nested function calls.
Returns a composable f(componentMethod/Component)
function.
Component
onPropChange(propsObject, [function])
onPropChange
has been deprecated and will be removed in the next major version. React Partial should be as simple as possible and it's easy to write these kind of composable utility functions without React Partial shipping with them.
NOTE: onPropChange uses componentWillReceiveProps
lifecycle method and listens to changes in props specified by the propsObject and calls the given function when prop has changed (using !==
equality check). This helps you to reduce boilerplate by not having to check whether prop has changed or not.
Returns a composable f(componentMethod/Component)
function.
componentWillReceiveProps
and onPropChange
can be used together.
createClass(specificationsObject, [function])
createClass can be used to define component methods as an object instead of using function composition.
Returns a composable f(componentMethod/Component)
function.
Component
addSpecs -> createClass
NOTE: addSpecs has been renamed to createClass and will be removed in the next major version.
Examples
1. Simple composition
const HelloWorld = <div>Hello propsworld</div> //second argument is omitted and partial function is returnedconst hello = const goodbye = //this allows you to add more functionality to an already existing wrapperconst helloAndGoodbye = //HelloWorld is augmented with both hello's and goodbye's functionalityHelloWorld
You can also write the above with more inline aesthetic:
HelloWorld
2. Combining multiple lifecycle methods
//combine lets you get rid of deeply nested function calls when dealing with multiple methodsconst wrapper = ; const Timer = <div>propstimer</div> Timer
3. Creating reusable containers
React Partial doesn't add any new functionality to React but it guides you separate pure UI components from logical components. It guides you to write composable higher order components with well defined functionality and can be then applied to any component. This is a very powerful pattern, allowing you to write declarative code and potentially greatly minimizing the amount of stateful components in your codebase.
//MyComponent.js const Component = <div>JSON</div> /** * Creates a component that: * - re-renders only when foo or bar change * - fetches foo, bar and baz from redux store as props to itself, * if the data is not in store, corresponding actions are called to populate it */ Component
//containers.js /** * - Only re-renders component when some of the given props change * - If no props are given, whole newProps is used */const updateOnPropChange = { const propsToCheck = customProps return } /** * - Fetches given data from store (Redux syntax assumed in example) * - calls actions to populate store if data is not yet there */const dependencies = { const deps = dependencies return }
As you can see, this neatly lets you abstract away the nitty-gritty of creating stateful components.
4. Multiple same lifecycle methods
Because components can be composed, it's important for them to work like mixins as multiple components can define same lifecycle methods. Instead of having to worry about how to compose functions so that all lifecycle methods get called, React Partial calls all the lifecycle methods in the same way mixins do:
const Component = <div>propsfoo + propsbar</div> Component
License
MIT