Live rendering lets you render your state on the fly on your renderer, no need to have a dedicated component to act as an intermediary.
There are three mechanisms for live rendering.
Direct
Data only
You can use the method connectLive from the ConanState object directly.
It takes a renderer function as argument.
All you need is to be able to access the ConanState instance.
{counterState$.connectLive(data => (<h1>{data.counter}</h1>))}
import {counterState$} from "../../state/counter.state$";
<button onClick={counterState$.do.increment}>Increment!</button>
<button onClick={counterState$.do.decrement}>Decrement!</button>
{counterState$.connectLive(data=>(<div>
<h1>{data.counter}</h1>
</div>
))}
Data and Monitor Info
{
counterState$
.tuple(counterState$.asyncState)
.connectLive((data, monitorInfo) =>
(<h1>{data.counter} - {monitorInfo.status}</h1>)
)
}
HOC
We can also use a High Order Component with live rendering, by using the components StateLive and ContextStateLive:
import {ContextStateLive, StateLive} from "conan-js-core";
import { counterState$ } from "../../state/counter.state$";
<StateLive from={counterState$} renderer={(data, actions) => (<div>
<button onClick={actions.increment}>Increment!</button>
<button onClick={actions.decrement}>Decrement!</button>
</div>)}/>;
};
<ContextStateLive renderer={data => (<h1>{data.counter}</h1>)}/>
import {ContextStateLive, StateLive} from "conan-js-core";
import {CounterActions, CounterData, counterState$} from "../../state/counter.state$";
<StateLive<CounterData, CounterActions>
from={counterState$}
renderer={(data, actions)=>(
<div>
<button onClick={actions.increment}>Increment!</button>
<button onClick={actions.decrement}>Decrement!</button>
<CounterDisplay/>
</div>
)}
/>
<ContextStateLive <CounterData>
renderer={data => (
<h1>{data.counter}</h1>
)}
/>
Composition
Live rendering can also be used with composition. ConanJs provides the functions contextStateLive and stateLive for it:
import {contextStateLive, stateLive} from "conan-js-core";
import { counterState$ } from "../../state/counter.state$";
stateLive(counterState$, (data, actions) => (<div>
<button onClick={actions.increment}>Increment!</button>
<button onClick={actions.decrement}>Decrement!</button>
<CounterDisplay />
</div>));
contextStateLive(data => (<h1>{data.counter}</h1>))
import {contextStateLive, stateLive} from "conan-js-core";
import {CounterActions, CounterData, counterState$} from "../../state/counter.state$";
stateLive<CounterData, CounterActions>(
counterState$,
(data, actions) => (
<div>
<button onClick={actions.increment}>Increment!</button>
<button onClick={actions.decrement}>Decrement!</button>
<CounterDisplay/>
</div>
)
)
contextStateLive<CounterData>( data => (
<h1>{data.counter}</h1>
));
Please take a look at this code sandbox to see al the subscription approaches working: