101 lines
1.7 KiB
JavaScript
101 lines
1.7 KiB
JavaScript
import React from 'react';
|
|
|
|
const canUseDOM = !!(
|
|
(typeof window !== 'undefined' && window.document && window.document.createElement)
|
|
);
|
|
|
|
export class StateTree
|
|
{
|
|
state = {}
|
|
subs = {}
|
|
context = {}
|
|
instance = null
|
|
|
|
constructor(context)
|
|
{
|
|
this.context = context || {};
|
|
}
|
|
|
|
get()
|
|
{
|
|
return this.state;
|
|
}
|
|
|
|
set(state)
|
|
{
|
|
this.state = state;
|
|
}
|
|
|
|
setInstance(instance)
|
|
{
|
|
this.instance = instance;
|
|
}
|
|
|
|
update()
|
|
{
|
|
if (this.instance)
|
|
{
|
|
this.state = this.instance.state;
|
|
}
|
|
for (const k in this.subs)
|
|
{
|
|
this.subs[k].update();
|
|
}
|
|
}
|
|
|
|
export()
|
|
{
|
|
const r = {
|
|
state: this.state,
|
|
subs: {},
|
|
};
|
|
for (const k in this.subs)
|
|
{
|
|
r.subs[k] = this.subs[k].export();
|
|
}
|
|
return r;
|
|
}
|
|
|
|
import(st)
|
|
{
|
|
this.state = st.state;
|
|
this.subs = {};
|
|
for (const k in st.subs)
|
|
{
|
|
this.sub(k).import(st.subs[k]);
|
|
}
|
|
}
|
|
|
|
sub(key)
|
|
{
|
|
if (!this.subs[key])
|
|
{
|
|
this.subs[key] = new StateTree(this.context);
|
|
}
|
|
return this.subs[key];
|
|
}
|
|
}
|
|
|
|
export class StateTreeComponent extends React.Component
|
|
{
|
|
constructor(props)
|
|
{
|
|
super(props);
|
|
if (props.state)
|
|
{
|
|
this.state = props.state.get();
|
|
this.ctx = props.state.context;
|
|
this.props.state.setInstance(this);
|
|
}
|
|
}
|
|
|
|
componentWillUnmount()
|
|
{
|
|
if (this.props.state)
|
|
{
|
|
this.props.state.set(this.state);
|
|
this.props.state.setInstance(null);
|
|
}
|
|
}
|
|
}
|