or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-hooks.mdconcurrency-helpers.mdcore-hooks.mdfamily-patterns.mdindex.mdloadable-system.mdmemory-management.mdroot-provider.mdstate-definition.md

core-hooks.mddocs/

0

# Core Hooks

1

2

Essential React hooks for reading and writing Recoil state with automatic subscriptions. These hooks form the primary interface between React components and Recoil state.

3

4

## Capabilities

5

6

### Reading State

7

8

Hooks for reading atom and selector values with automatic component subscriptions.

9

10

```typescript { .api }

11

/**

12

* Returns the value of an atom or selector (readonly or writeable) and

13

* subscribes the components to future updates of that state.

14

*/

15

function useRecoilValue<T>(recoilValue: RecoilValue<T>): T;

16

17

/**

18

* Returns a Loadable representing the status of the given Recoil state

19

* and subscribes the component to future updates of that state. Useful

20

* for working with async selectors.

21

*/

22

function useRecoilValueLoadable<T>(recoilValue: RecoilValue<T>): Loadable<T>;

23

```

24

25

**Usage Examples:**

26

27

```typescript

28

import React from 'react';

29

import { useRecoilValue, useRecoilValueLoadable } from 'recoil';

30

31

// Reading synchronous state

32

function UserName() {

33

const userName = useRecoilValue(userNameState);

34

return <div>Hello, {userName}!</div>;

35

}

36

37

// Reading async state with loadable

38

function AsyncUserProfile() {

39

const userProfileLoadable = useRecoilValueLoadable(userProfileState);

40

41

switch (userProfileLoadable.state) {

42

case 'hasValue':

43

return <div>Profile: {userProfileLoadable.contents.name}</div>;

44

case 'loading':

45

return <div>Loading profile...</div>;

46

case 'hasError':

47

return <div>Error: {userProfileLoadable.contents.message}</div>;

48

}

49

}

50

```

51

52

### Reading and Writing State

53

54

Hooks that provide both the value and setter for writeable Recoil state.

55

56

```typescript { .api }

57

/**

58

* Returns a tuple where the first element is the value of the recoil state

59

* and the second is a setter to update that state. Subscribes component

60

* to updates of the given state.

61

*/

62

function useRecoilState<T>(recoilState: RecoilState<T>): [T, SetterOrUpdater<T>];

63

64

/**

65

* Returns a tuple where the first element is a Loadable and the second

66

* element is a setter function to update the given state. Subscribes

67

* component to updates of the given state.

68

*/

69

function useRecoilStateLoadable<T>(recoilState: RecoilState<T>): [Loadable<T>, SetterOrUpdater<T>];

70

71

type SetterOrUpdater<T> = (valOrUpdater: ((currVal: T) => T) | T) => void;

72

```

73

74

**Usage Examples:**

75

76

```typescript

77

import React from 'react';

78

import { useRecoilState, useRecoilStateLoadable } from 'recoil';

79

80

// Basic state management

81

function Counter() {

82

const [count, setCount] = useRecoilState(countState);

83

84

return (

85

<div>

86

<p>Count: {count}</p>

87

<button onClick={() => setCount(count + 1)}>Increment</button>

88

<button onClick={() => setCount(c => c - 1)}>Decrement</button>

89

</div>

90

);

91

}

92

93

// Form input with state

94

function NameInput() {

95

const [name, setName] = useRecoilState(nameState);

96

97

return (

98

<input

99

value={name}

100

onChange={(e) => setName(e.target.value)}

101

placeholder="Enter your name"

102

/>

103

);

104

}

105

106

// Async state with loadable

107

function AsyncDataEditor() {

108

const [dataLoadable, setData] = useRecoilStateLoadable(asyncDataState);

109

110

const handleSave = (newData) => {

111

setData(newData); // This will trigger async update

112

};

113

114

if (dataLoadable.state === 'loading') {

115

return <div>Loading...</div>;

116

}

117

118

if (dataLoadable.state === 'hasError') {

119

return <div>Error loading data</div>;

120

}

121

122

return (

123

<div>

124

<DataEditor

125

data={dataLoadable.contents}

126

onSave={handleSave}

127

/>

128

</div>

129

);

130

}

131

```

132

133

### Writing State Only

134

135

Hooks for updating state without subscribing to value changes.

136

137

```typescript { .api }

138

/**

139

* Returns a setter function for updating Recoil state. Does not subscribe

140

* the component to the given state.

141

*/

142

function useSetRecoilState<T>(recoilState: RecoilState<T>): SetterOrUpdater<T>;

143

144

/**

145

* Returns a function that will reset the given state to its default value.

146

*/

147

function useResetRecoilState(recoilState: RecoilState<any>): () => void;

148

```

149

150

**Usage Examples:**

151

152

```typescript

153

import React from 'react';

154

import { useSetRecoilState, useResetRecoilState } from 'recoil';

155

156

// Component that only updates state (no subscription)

157

function ActionButtons() {

158

const setCount = useSetRecoilState(countState);

159

const resetUser = useResetRecoilState(userState);

160

161

return (

162

<div>

163

<button onClick={() => setCount(c => c + 1)}>

164

Increment Counter

165

</button>

166

<button onClick={resetUser}>

167

Reset User

168

</button>

169

</div>

170

);

171

}

172

173

// Event handler that updates multiple states

174

function useDataActions() {

175

const setLoading = useSetRecoilState(loadingState);

176

const setError = useSetRecoilState(errorState);

177

const setData = useSetRecoilState(dataState);

178

179

const loadData = async () => {

180

setLoading(true);

181

setError(null);

182

183

try {

184

const response = await fetch('/api/data');

185

const data = await response.json();

186

setData(data);

187

} catch (error) {

188

setError(error.message);

189

} finally {

190

setLoading(false);

191

}

192

};

193

194

return { loadData };

195

}

196

```

197

198

### Transition Support (Experimental)

199

200

Hooks with React Concurrent Mode transition support for performance optimization.

201

202

```typescript { .api }

203

/**

204

* Experimental version of useRecoilValue with useTransition() support

205

*/

206

function useRecoilValue_TRANSITION_SUPPORT_UNSTABLE<T>(recoilValue: RecoilValue<T>): T;

207

208

/**

209

* Experimental version of useRecoilValueLoadable with useTransition() support

210

*/

211

function useRecoilValueLoadable_TRANSITION_SUPPORT_UNSTABLE<T>(recoilValue: RecoilValue<T>): Loadable<T>;

212

213

/**

214

* Experimental version of useRecoilState with useTransition() support

215

*/

216

function useRecoilState_TRANSITION_SUPPORT_UNSTABLE<T>(recoilState: RecoilState<T>): [T, SetterOrUpdater<T>];

217

```

218

219

**Usage Examples:**

220

221

```typescript

222

import React, { useTransition } from 'react';

223

import { useRecoilValue_TRANSITION_SUPPORT_UNSTABLE } from 'recoil';

224

225

// Component using transition-compatible hooks

226

function SearchResults() {

227

const [isPending, startTransition] = useTransition();

228

const searchResults = useRecoilValue_TRANSITION_SUPPORT_UNSTABLE(searchResultsState);

229

230

const handleSearch = (query) => {

231

startTransition(() => {

232

// This update will be marked as a transition

233

setSearchQuery(query);

234

});

235

};

236

237

return (

238

<div>

239

{isPending ? <div>Searching...</div> : null}

240

<SearchResultsList results={searchResults} />

241

</div>

242

);

243

}

244

```

245

246

### State Information (Unstable)

247

248

Debugging hook for inspecting state metadata and dependencies.

249

250

```typescript { .api }

251

/**

252

* Returns current info about an atom or selector

253

*/

254

function useGetRecoilValueInfo_UNSTABLE(): <T>(recoilValue: RecoilValue<T>) => RecoilStateInfo<T>;

255

256

interface RecoilStateInfo<T> {

257

loadable?: Loadable<T>;

258

isActive: boolean;

259

isSet: boolean;

260

isModified: boolean;

261

type: 'atom' | 'selector';

262

deps: Iterable<RecoilValue<T>>;

263

subscribers: {

264

nodes: Iterable<RecoilValue<T>>;

265

components: Iterable<ComponentInfo>;

266

};

267

}

268

269

interface ComponentInfo {

270

name: string;

271

}

272

```

273

274

**Usage Examples:**

275

276

```typescript

277

import React from 'react';

278

import { useGetRecoilValueInfo_UNSTABLE } from 'recoil';

279

280

// Debug component for inspecting state

281

function StateDebugger({ recoilValue }) {

282

const getRecoilValueInfo = useGetRecoilValueInfo_UNSTABLE();

283

const info = getRecoilValueInfo(recoilValue);

284

285

return (

286

<div>

287

<h3>State Info</h3>

288

<p>Type: {info.type}</p>

289

<p>Is Active: {info.isActive.toString()}</p>

290

<p>Is Set: {info.isSet.toString()}</p>

291

<p>Is Modified: {info.isModified.toString()}</p>

292

<p>Dependencies: {Array.from(info.deps).length}</p>

293

<p>Component Subscribers: {Array.from(info.subscribers.components).length}</p>

294

</div>

295

);

296

}

297

```

298

299

### Cache Refresh (Unstable)

300

301

Hook for manually clearing selector caches to force reevaluation.

302

303

```typescript { .api }

304

/**

305

* Clears the cache for a selector causing it to be reevaluated

306

*/

307

function useRecoilRefresher_UNSTABLE(recoilValue: RecoilValue<any>): () => void;

308

```

309

310

**Usage Examples:**

311

312

```typescript

313

import React from 'react';

314

import { useRecoilRefresher_UNSTABLE } from 'recoil';

315

316

// Component with manual refresh capability

317

function DataDisplay() {

318

const data = useRecoilValue(asyncDataState);

319

const refreshData = useRecoilRefresher_UNSTABLE(asyncDataState);

320

321

return (

322

<div>

323

<div>Data: {JSON.stringify(data)}</div>

324

<button onClick={refreshData}>

325

Refresh Data

326

</button>

327

</div>

328

);

329

}

330

```