# React Usage

React-specific rule: pure functions carry business logic; hooks carry React composition; components carry rendering.

## Required Order

1. Extract pure predicate/result functions outside React.
2. Test the pure functions directly.
3. Create a shared hook that gathers props/state/API data and calls those functions.
4. Let components consume hook results and render.

Do not put complex business expressions directly in JSX, event handlers, `useMemo`, `useEffect`, or component bodies when they can be named and reused.

## Pattern

```ts
// trainLogic.ts
export function isBasicMember(ctx: TrainContext) {
  return ctx.accountLevel === 2;
}

export function isPowerEnough(ctx: TrainContext) {
  return ctx.remainingPower >= ctx.expectedConsumePower;
}

export function isMeetTrainCondition(ctx: TrainContext) {
  return isPowerEnough(ctx) && isMeetSdxlCondition(ctx);
}

export function getTrainButtonState(ctx: TrainContext) {
  return {
    disabled: isBasicMember(ctx) && isMeetTrainCondition(ctx) && !ctx.isPreprocessed,
    text: resolveTrainButtonText(ctx),
    showPowerPrompt: isPowerNotEnough(ctx),
  };
}
```

```tsx
// useTrainButtonState.ts
export function useTrainButtonState(ctx: TrainContext) {
  return useMemo(() => getTrainButtonState(ctx), [
    ctx.accountLevel,
    ctx.remainingPower,
    ctx.expectedConsumePower,
    ctx.currentSelectedModelId,
    ctx.isPreprocessed,
  ]);
}
```

```tsx
// TrainButton.tsx
export function TrainButton(props: Props) {
  const button = useTrainButtonState(props.trainContext);

  return (
    <Button disabled={button.disabled}>
      {button.text}
    </Button>
  );
}
```

## Hook Rules

- Hooks may assemble context from props, stores, queries, feature flags, and route state.
- Hooks should call domain functions; they should not become the only place where domain logic exists.
- If logic is needed outside React, it must already exist as a pure function.
- Use `useMemo` only as a React performance/wiring concern, not as the primary abstraction.
- Keep dependency arrays explicit and aligned with the context fields used by the pure function.

## Component Rules

- Components should not contain multi-clause business conditions in JSX.
- Components should not duplicate predicates already defined in domain logic.
- Event handlers should call named result/policy functions when deciding behavior.
- Snapshot or component tests are not a substitute for predicate function tests.
