UNPKG

preact

Version:

Tiny & fast Component-based virtual DOM framework.

103 lines (89 loc) 3.6 kB
import { FORCE_RENDER } from './constants'; import { extend, clone, isFunction } from './util'; import { createLinkedState } from './linked-state'; import { renderComponent } from './vdom/component'; import { enqueueRender } from './render-queue'; /** Base Component class, for he ES6 Class method of creating Components * @public * * @example * class MyFoo extends Component { * render(props, state) { * return <div />; * } * } */ export function Component(props, context) { /** @private */ this._dirty = true; // /** @public */ // this._disableRendering = false; // /** @public */ // this.prevState = this.prevProps = this.prevContext = this.base = this.nextBase = this._parentComponent = this._component = this.__ref = this.__key = this._linkedStates = this._renderCallbacks = null; /** @public */ this.context = context; /** @type {object} */ this.props = props; /** @type {object} */ if (!this.state) this.state = {}; } extend(Component.prototype, { /** Returns a `boolean` value indicating if the component should re-render when receiving the given `props` and `state`. * @param {object} nextProps * @param {object} nextState * @param {object} nextContext * @returns {Boolean} should the component re-render * @name shouldComponentUpdate * @function */ // shouldComponentUpdate() { // return true; // }, /** Returns a function that sets a state property when called. * Calling linkState() repeatedly with the same arguments returns a cached link function. * * Provides some built-in special cases: * - Checkboxes and radio buttons link their boolean `checked` value * - Inputs automatically link their `value` property * - Event paths fall back to any associated Component if not found on an element * - If linked value is a function, will invoke it and use the result * * @param {string} key The path to set - can be a dot-notated deep key * @param {string} [eventPath] If set, attempts to find the new state value at a given dot-notated path within the object passed to the linkedState setter. * @returns {function} linkStateSetter(e) * * @example Update a "text" state value when an input changes: * <input onChange={ this.linkState('text') } /> * * @example Set a deep state value on click * <button onClick={ this.linkState('touch.coords', 'touches.0') }>Tap</button */ linkState(key, eventPath) { let c = this._linkedStates || (this._linkedStates = {}); return c[key+eventPath] || (c[key+eventPath] = createLinkedState(this, key, eventPath)); }, /** Update component state by copying properties from `state` to `this.state`. * @param {object} state A hash of state properties to update with new values */ setState(state, callback) { let s = this.state; if (!this.prevState) this.prevState = clone(s); extend(s, isFunction(state) ? state(s, this.props) : state); if (callback) (this._renderCallbacks = (this._renderCallbacks || [])).push(callback); enqueueRender(this); }, /** Immediately perform a synchronous re-render of the component. * @private */ forceUpdate() { renderComponent(this, FORCE_RENDER); }, /** Accepts `props` and `state`, and returns a new Virtual DOM tree to build. * Virtual DOM is generally constructed via [JSX](http://jasonformat.com/wtf-is-jsx). * @param {object} props Props (eg: JSX attributes) received from parent element/component * @param {object} state The component's current state * @param {object} context Context object (if a parent component has provided context) * @returns VNode */ render() {} });