MCPcopy Create free account
hub / github.com/middleapi/orpc / useServerAction

Function useServerAction

packages/react/src/hooks/server-action.ts:104–180  ·  view source on GitHub ↗
(
  action: ActionableClient<TInput, TOutput, TError>,
  options: UseServerActionOptions<TInput, TOutput, UnactionableError<TError>> = {},
)

Source from the content-addressed store, hash-verified

102 * @see {@link https://orpc.dev/docs/server-action#useserveraction-hook Server Action Hook Docs}
103 */
104export function useServerAction<TInput, TOutput, TError extends ORPCErrorJSON<any, any>>(
105 action: ActionableClient<TInput, TOutput, TError>,
106 options: UseServerActionOptions<TInput, TOutput, UnactionableError<TError>> = {},
107): UseServerActionResult<TInput, TOutput, UnactionableError<TError>> {
108 const [state, setState] = useState<Omit<
109 | UseServerActionIdleResult<TInput, TOutput, UnactionableError<TError>>
110 | UseServerActionSuccessResult<TInput, TOutput, UnactionableError<TError>>
111 | UseServerActionErrorResult<TInput, TOutput, UnactionableError<TError>>,
112 keyof UseServerActionResultBase<TInput, TOutput, UnactionableError<TError>> | 'executedAt' | 'input'
113 >>(INITIAL_STATE)
114
115 const executedAtRef = useRef<Date | undefined>(undefined)
116 const [input, setInput] = useState<TInput | undefined>(undefined)
117 const [isPending, startTransition] = useTransition()
118
119 const reset = useCallback(() => {
120 executedAtRef.current = undefined
121 setInput(undefined)
122 setState({ ...INITIAL_STATE })
123 }, [])
124
125 const execute = useCallback(async (input: TInput, executeOptions: UseServerActionExecuteOptions<TInput, TOutput, UnactionableError<TError>> = {}) => {
126 const executedAt = new Date()
127 executedAtRef.current = executedAt
128
129 setInput(input)
130
131 return new Promise((resolve) => {
132 startTransition(async () => {
133 const result = await safe(intercept(
134 [...toArray(options.interceptors), ...toArray(executeOptions.interceptors)],
135 { input: input as TInput },
136 async ({ input }) => action(input).then(([error, data]) => {
137 if (error) {
138 throw createORPCErrorFromJson(error)
139 }
140
141 return data as TOutput
142 }),
143 ))
144
145 /**
146 * If multiple execute calls are made in parallel, only the last one will be effective.
147 */
148 if (executedAtRef.current === executedAt) {
149 setState({
150 data: result.data,
151 error: result.error as any,
152 isIdle: false,
153 isPending: false,
154 isSuccess: !result.error,
155 isError: !!result.error,
156 status: !result.error ? 'success' : 'error',
157 })
158 }
159
160 resolve(result)
161 })

Callers 4

OrpcServerActionFunction · 0.90

Calls 6

safeFunction · 0.90
interceptFunction · 0.90
toArrayFunction · 0.90
createORPCErrorFromJsonFunction · 0.90
actionFunction · 0.85
thenMethod · 0.80

Tested by

no test coverage detected