Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | 2x 2x 14x 14x 14x 14x 14x 27x 16x 16x 2x 2x 7x 7x 7x 3x 4x 7x 7x 7x 8x 8x 8x 6x 8x 14x 14x 14x 14x 14x 14x 10x 11x 9x 1x 2x 2x 2x 13x 13x 8x 24x 2x 22x 22x 27x 13x 13x 13x 14x 14x 14x 14x 22x 22x 23x 24x 11x 11x 11x | import React from 'react' import createReactContext from 'create-react-context' import produce from 'immer' const Context = createReactContext() let ListenerID = 0 export class Controller { constructor() { this.state = {} this.setFaterState = [] this.produce = produce this.isDirty = false this.map = new Map() } addListener = (setState, id) => { if (!this.map.get(id)) { this.map.set(id, true) this.setFaterState.push({ fn: setState, id: id }) } } removeListener = id => { this.map.delete(id) this.setFaterState = this.setFaterState.filter(i => i.id !== id) } setState(partial, cb) { this.isDirty = true setImmediate(() => { let newState if (typeof partial === 'function') { newState = produce(this.state, partial) } else { newState = { ...this.state, ...partial } } this.state = newState let callback_length = this.setFaterState.length this.setFaterState.forEach(({ fn, id }) => { fn(this.state, () => { callback_length-- if (callback_length <= 0) { this.isDirty = false } cb && cb(this.state) }) }) // no matter what `newState` is, we have to set state to original state }) } } export class Listen extends React.Component { constructor(props) { ListenerID++ super(props) this.id = ListenerID this.state = {} this.Machines = [] this._isMounted = false } shouldComponentUpdate() { for (let i in this.Machines) { if (this.Machines[i].isDirty === true) { return true } } return false } componentWillUnmount() { this.Machines.forEach(m => { m.removeListener(this.id) }) this._isMounted = false } componentDidMount() { this._isMounted = true this.props.didMount && this.props.didMount.apply(null, this.Machines) } _noopUpdate = (state, cb) => { this.setState({}, cb) } createMachine = context => { if (context === void 666) { throw new Error('<Listen/> components must be wrapped in a <Provider/>') } const MachineConstructor = this.props.to let newMachines = MachineConstructor.map(Machine => { if (context.get(Machine)) { const instance = context.get(Machine) instance.addListener(this._noopUpdate.bind(this), this.id) return instance } let newInstance = new Machine() newInstance.addListener(this._noopUpdate.bind(this), this.id) context.set(Machine, newInstance) return newInstance }) this.Machines = newMachines return this.Machines } render() { return ( <Context.Consumer>{context => this.props.children.apply(null, this.createMachine(context))}</Context.Consumer> ) } } export class Provider extends React.Component { render() { return ( <Context.Consumer> {topState => { let childState = new Map(topState) return <Context.Provider value={childState}>{this.props.children}</Context.Provider> }} </Context.Consumer> ) } } |