DEV Community 👩‍💻👨‍💻

Discussion on: What happened to Components being just a visual thing?

 
3shain profile image
3Shain • Edited on

props will be involved whenever you use a component more than once on the same page to represent separate business entities.

As I said before

I need to mention that the identity of Component is not always the same as the identity of Instance of Component. That's why in some framework you need to specify the key.

although there are no real key here but different update props are passed to identify different entities. In certain degree it's the mismatch between UI and application proved again.

and the solution is fairly simple... encapsulate High Order Component

although it's not necessary to involve any architecture decision, I'm placing the kairo's solution here

const [External, ExternalImpl] = createConcreteConcern('External', function*() {
    const [leftValue, setLeft] = yield* State(0);
    const [rightValue, setRight] = yield* State(0);
    return {
        leftValue, rightValue,
        setLeft, setRight
    }
}); // a shortcut of `createConcern` with a default implementation

const Value = UI(function*({value, setValue}:{value:Cell<number>, setValue:Setter<number>}) {
    const onChange = e => setValue(e.target.value);
    return Component((_,$)=>(<span><input value={$(value)} onChange={onChange}/></span>));
});

const App = UI(function*() {
    const {leftValue, rightValue, setLeft, setRight} = yield* External;
    const Left = yield* Include(Value.withProps({value:leftValue, setValue:setLeft}));
    const Right = yield* Include(Value.withProps({value:rightValue, setValue:setRight}));
    return Component((_,$)=>(
    <div className="App">
      <h1>Totals</h1>
      <Left />
      <Right />
      total is {$(leftValue) + $(rightValue)}
    </div>));
});
Enter fullscreen mode Exit fullscreen mode

notably I made Value fully controlled because it's unnecessary to have a local state as there is already a source of truth.