Repository URL to install this package:
|
Version:
3.0.10 ▾
|
/**
* @see https://codesandbox.io/s/ppw027o70 (.map example)
* @see https://codesandbox.io/s/m33vrr37r8 (this code in this file)
*/
import React from 'react'
import { isObservable, observable } from 'xmobx/mobx'
import { ReactChild, ReactElement, Ref } from 'react'
import { isString, isNumber, isObj } from 'exotic'
type ObservableDebugItem = {
component: ReactElement<any> | any
state: any
}
type Scoped = {
ref: Ref<any> | ReactElement<any>
// setRef(ref: Ref<any>): void
}
const observableList: ObservableDebugItem[] = []
window.observableList = observableList
const fromComponentToPropsThatPickupObservablesAndRef = (
component: ReactElement<any>
) => {
// scope this so we can lazily get the ref
const scoped: Scoped = {
ref: component,
}
// @note it's frozen
const props = {
...component.props,
/**
* @see https://github.com/facebook/react/issues/8873#issuecomment-275423780
*/
ref: (ref: any) => {
scoped.ref = ref
},
}
// find the observables, put them in the list
Object.keys(props).forEach(key => {
const value = props[key]
if (isObj(value) && isObservable(value)) {
const entry = {
state: value,
get component() {
return scoped.ref
},
}
observableList.push(entry)
}
})
return props
}
const traverseChildren = (child: ReactChild) => {
if (isString(child) || isNumber(child)) {
return child
}
const props = fromComponentToPropsThatPickupObservablesAndRef(child)
// traverse
if (props.children) {
props.children = traverseChildren(props.children)
}
return React.cloneElement(child, props)
}
/**
* @example <Debug>{...anything}</Debug>
*/
class Debug extends React.Component {
render() {
const { children } = this.props
return React.Children.map(children, traverseChildren)
}
}
export { Debug }
export default Debug