"[RFC] React API" diff by Lee Byron, March 10 2013
After some discussion with Tom Occhino, Jordan Walke and Sebastian Markbage I've arrived at an API naming scheme which seeks to define a pattern for naming methods, clarify which methods are internal vs public and reduce the number of concepts you need to be familiar with in React.
-
Concepts
- component - a ReactComponent instance
- state - internal state to a component
- props - external state to a component
- markup - the stringy htmlish stuff components generate
- DOM - the document and elements within the document.
-
Actions
- mount - to put a component into a DOM
- initialize - to prepare a component for rendering
- update - a transition of state (and props) resulting a render.
- render - a side-effect-free process to get the representation (markup) of a component.
- validate - make assertions about something created and provided
- destroy - opposite of initialize
-
Operands
- create - make a new thing
- get - get an existing thing
- set - merge into existing
- replace - replace existing
- receive - respond to new data
- force - skip checks to do action
-
Notifications
- shouldObjectAction
- objectWillAction
- objectDidAction
The result of this can be seen most clearly by ReactCompositeComponentInterface
which defines the methods a custom component is expected to implement. They come in two flavors: "life cycle" methods like "initialize", "render" and "destructor" and "delegate" methods like "componentWillReceiveProps"
This diff removed a number of hooks from the base ReactCompositeComponent but added a number of delegate style methods to the spec. Let me talk though these replacements:
-
getAllRenderResults
,handleGenMarkupResults
,reconcileResults
- Instead of these I've addedcomponentWillUpdate
andcomponentDidUpdate
within which you can perform this yourself. These hooks were only used in Layer and that component has been updated. -
handleUpdate
- This hook let you do some arbitary work before callingupdateUI()
, the most common work is to mutate state based on some transition in properties. For that case you havecomponentWillReceiveProps(newProps)
within which you can callthis.setState()
. Another case is to check for pairity in the case your render function is pure, for that case you haveshouldComponentUpdate(newProps, newState)
which lets you return false if you don't want to update. The final usage is if you want to completely take over from React (like fART) for which you haveupdateComponent
which is very similar except for that it's also called when state changes andthis.props
andthis.state
are up to date. -
onDOMReady - This hook was a little confusing as it's not referring to the browser event and doesn't cover all cases. This method has been renamed to
componentDidInitialize
which is called when a component is initially placed in the DOM. In addition,componentDidUpdate
is called when a component is updated in the DOM. These are places to place animation hooks. -
initialize
anddestructor
become delegate methodscomponentWillInitialize
andcomponentWillDestroy
.
updateUI
is deprecated, the only entry-points are setState
, replaceState
and forceUpdate
(a renaming of reconcile
).
The ReactCompositeComponentInterface
now describes for each method the rules by which it may be defined. Most are DEFINE_ONCE
which means we will yell at you if a mixin and spec implement the same function. Some are DEFINE_MANY
which allows mixins and spec to implement the same method without clobbering each other. This is useful as it provides a sort of "multiple inheritance" and allows mixins to use componentWillInitialize
and componentWillDestroy
without fear of being overwritten by the spec itself. Finally there is OVERRIDE_BASE
. While you're allowed to define whatever methods you want on your component, we check to ensure you're not overriding a method on the base ReactCompositeComponent class //unless// OVERRIDE_BASE
is provided.
Moves the "INITIALIZING" life cycle definition into ReactCompositeComponent
where it's used, loosening coupling between it and ReactComponent
. Also adds the life cycle states RECEIVING_PROPS
and RECEIVING_STATE
which clarifies the behavior of this.setState
while receiving new information. This allows componentWillReceiveProps
to work correctly.
setProps
, setState
, forceUpdate
, mountInNode
and others take a callback which is called after the transaction has completed mutating the DOM.
Uses the new delegate style API (and fixes a few lifecycle bugs)
componentWillDestroy
(previously destructor
) is now called right before the actual destruction occurs so you can access this.refs from this function.
I should mention that this was the beginning of a discussion with the team, and that discussion led to further improvements like changing componentDidInitialize and componentWillDestory to componentDidMount and componentWillUnmount