rsnext/packages/next/next-server/lib/side-effect.tsx
Tim Neutkens 2ba352da39 Move next-server back into next package (#8613)
* Initial move

* Make emitting work

* Update paths

* Remove leftover files

* Add correct externals configuration

* Import correct path

* Update path to work with ts-server test

* Update lib directory

* Compile next-server/lib
2019-09-04 10:00:54 -04:00

62 lines
1.3 KiB
TypeScript

import React, { Component } from 'react'
const isServer = typeof window === 'undefined'
type State = Array<React.ReactElement<any>> | undefined
type SideEffectProps = {
reduceComponentsToState: <T>(
components: Array<React.ReactElement<any>>,
props: T
) => State
handleStateChange?: (state: State) => void
inAmpMode?: boolean
}
export default () => {
const mountedInstances: Set<any> = new Set()
let state: State
function emitChange(component: React.Component<SideEffectProps>) {
state = component.props.reduceComponentsToState(
[...mountedInstances],
component.props
)
if (component.props.handleStateChange) {
component.props.handleStateChange(state)
}
}
return class extends Component<SideEffectProps> {
// Used when server rendering
static rewind() {
const recordedState = state
state = undefined
mountedInstances.clear()
return recordedState
}
constructor(props: any) {
super(props)
if (isServer) {
mountedInstances.add(this)
emitChange(this)
}
}
componentDidMount() {
mountedInstances.add(this)
emitChange(this)
}
componentDidUpdate() {
emitChange(this)
}
componentWillUnmount() {
mountedInstances.delete(this)
emitChange(this)
}
render() {
return null
}
}
}