# Effectful한 프론트엔드 프레임워크
## 컴포넌트
- `(props: P) => Effect<void, E, R | RenderScope>`
- `render(eff: Effect<void, never, RenderScope>)`에 넣어서 렌더링
## 이벤트
- 이벤트 핸들러는 이펙트를 반환할 수 있다.
- 이벤트 핸들러가 반환할 이펙트의 `R`이나 `E`가 해당 핸들러가 바인딩될 요소의 E로 전이될 수 있는가?
- 가능하다면 이벤트 핸들러에서 `Effect<R, E, unknown>`을 반환하도록 인터페이스를 구성하더라도 `R`, `E`를 적절하게 전이시킬 수 있음
- 근데 가능하다고 해도 이게 유저랜드 컴포넌트들이 임의의 이벤트 핸들러들에 대해 구현할 수 있을 만큼 충분히 쉬운가?
- 불가능하다면.... 모든 이벤트 핸들러는 `Effect<never, never, unknown>`를 반환해야 함
## 에러
- 컴포넌트가 반환한 `E`를 처리
- TS는 개별 JSX 요소가 반환한 `E`를 부모 요소의 `E`로 전이시킬 수 있을 만큼 똑똑한가?
- 가능하다면 컴포넌트를 별도 에러 핸들링 없이도 바로 JSX에서 사용할 수 있음
- 리렌더는 어떻게?
- ㅁ
- 불가능하다면... `E`를 핸들링한 후에야 JSX화시킬 수 있음
## 비동기
- Effect 특성상 비동기 렌더링 자체는 걍.... await하면 됨
- 근데 그걸 원하는 게 아님
- Suspense의 구현이 가능한가?
- 먼저 fallback을 띄우고, `children` 이펙트를 fork해서 실행한 다음, 실행이 끝나면 실행 결과를 그린다
- 리렌더는 어떻게?
- ㅁ
```ts=
const Comp = (props) => Effect.gen(function* () {
const [count, setCount] = yield* createSignal(0);
const doubleCount = yield* createDerived(pipe(
count,
Effect.map((count) => count * 2),
));
const asyncData = yield* createDerived(
Effect.gen(function* () {
const value = yield* doubleCount;
const data = yield* Fetch(value);
return data;
}),
);
yield* render(
Suspense({
children: El.div({
children: Effect.map(
asyncData,
(data) => `Data: ${data}`,
),
}),
fallback: El.div({ children: "Loading..." }),
}),
);
})
```