or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-routing.mdhistory.mdhooks.mdindex.mdlocation-context.mdnavigation.mdrouting.mdserver-rendering.mdutilities.md

location-context.mddocs/

0

# Location and Context

1

2

Location providers and consumer components for accessing current location state and navigation functions in React components.

3

4

## Capabilities

5

6

### LocationProvider Component

7

8

React context provider that manages location state and navigation functionality for the application.

9

10

```javascript { .api }

11

/**

12

* Context provider for location state and navigation functionality

13

* @param props - Provider configuration

14

*/

15

function LocationProvider(props: {

16

history?: History;

17

children: React.ReactNode | ((context: LocationContext) => React.ReactNode);

18

}): React.ReactElement;

19

20

interface LocationContext {

21

location: Location;

22

navigate: (to: string | number, options?: NavigateOptions) => Promise<void>;

23

}

24

25

interface History {

26

location: Location;

27

transitioning: boolean;

28

listen(listener: (event: HistoryEvent) => void): () => void;

29

navigate(to: string | number, options?: NavigateOptions): Promise<void>;

30

_onTransitionComplete(): void;

31

}

32

33

interface HistoryEvent {

34

location: Location;

35

action: "PUSH" | "POP";

36

}

37

```

38

39

**Props:**

40

- `history` (History, optional) - Custom history instance (defaults to globalHistory)

41

- `children` - React nodes or render function receiving context

42

43

**Usage Examples:**

44

45

```javascript

46

import React from "react";

47

import { LocationProvider, createHistory, createMemorySource } from "@reach/router";

48

49

// Basic usage with default history

50

const App = () => (

51

<LocationProvider>

52

<AppContent />

53

</LocationProvider>

54

);

55

56

// Custom history for testing

57

const TestApp = () => {

58

const testHistory = createHistory(createMemorySource("/test-path"));

59

60

return (

61

<LocationProvider history={testHistory}>

62

<AppContent />

63

</LocationProvider>

64

);

65

};

66

67

// Render prop pattern

68

const App = () => (

69

<LocationProvider>

70

{({ location, navigate }) => (

71

<div>

72

<p>Current path: {location.pathname}</p>

73

<button onClick={() => navigate("/about")}>Go to About</button>

74

<AppContent />

75

</div>

76

)}

77

</LocationProvider>

78

);

79

80

// Multiple providers for different app sections

81

const MultiProviderApp = () => (

82

<div>

83

<LocationProvider history={mainHistory}>

84

<MainApp />

85

</LocationProvider>

86

87

<LocationProvider history={adminHistory}>

88

<AdminPanel />

89

</LocationProvider>

90

</div>

91

);

92

```

93

94

### Location Consumer Component

95

96

Component for consuming location context without using hooks (useful for class components or render props).

97

98

```javascript { .api }

99

/**

100

* Consumer component for accessing location context

101

* @param props - Consumer configuration

102

*/

103

function Location(props: {

104

children: (context: LocationContext) => React.ReactNode;

105

}): React.ReactElement;

106

```

107

108

**Usage Examples:**

109

110

```javascript

111

import React from "react";

112

import { Location } from "@reach/router";

113

114

// Basic render prop usage

115

const LocationInfo = () => (

116

<Location>

117

{({ location, navigate }) => (

118

<div>

119

<h2>Current Location</h2>

120

<p>Path: {location.pathname}</p>

121

<p>Search: {location.search}</p>

122

<button onClick={() => navigate("/")}>Home</button>

123

</div>

124

)}

125

</Location>

126

);

127

128

// Class component usage

129

class ClassComponent extends React.Component {

130

render() {

131

return (

132

<Location>

133

{({ location, navigate }) => (

134

<div>

135

<p>Location in class: {location.pathname}</p>

136

<button onClick={() => navigate("/next")}>

137

Navigate

138

</button>

139

</div>

140

)}

141

</Location>

142

);

143

}

144

}

145

146

// Conditional rendering based on location

147

const ConditionalContent = () => (

148

<Location>

149

{({ location }) => (

150

<>

151

{location.pathname === "/" && <HomePage />}

152

{location.pathname.startsWith("/admin") && <AdminWarning />}

153

{location.search.includes("debug=true") && <DebugPanel />}

154

</>

155

)}

156

</Location>

157

);

158

159

// Navigation controls

160

const NavigationControls = () => (

161

<Location>

162

{({ location, navigate }) => (

163

<div className="nav-controls">

164

<button

165

onClick={() => navigate(-1)}

166

disabled={!window.history.state}

167

>

168

Back

169

</button>

170

<span>Current: {location.pathname}</span>

171

<button onClick={() => navigate("/")}>

172

Home

173

</button>

174

</div>

175

)}

176

</Location>

177

);

178

```

179

180

### Context Integration Patterns

181

182

Common patterns for integrating location context with other React patterns.

183

184

**Usage Examples:**

185

186

```javascript

187

// Higher-order component pattern

188

const withLocation = (Component) => {

189

return (props) => (

190

<Location>

191

{(locationProps) => (

192

<Component {...props} {...locationProps} />

193

)}

194

</Location>

195

);

196

};

197

198

const EnhancedComponent = withLocation(({ location, navigate, ...props }) => (

199

<div>

200

<p>Path: {location.pathname}</p>

201

<MyComponent {...props} />

202

</div>

203

));

204

205

// Custom hook using context (alternative to useLocation)

206

const useLocationContext = () => {

207

const [context, setContext] = React.useState(null);

208

209

return (

210

<Location>

211

{(locationContext) => {

212

if (!context) setContext(locationContext);

213

return null;

214

}}

215

</Location>

216

);

217

};

218

219

// Context provider wrapper

220

const LocationContextProvider = ({ children }) => {

221

return (

222

<LocationProvider>

223

<Location>

224

{(locationContext) => (

225

<MyCustomContext.Provider value={locationContext}>

226

{children}

227

</MyCustomContext.Provider>

228

)}

229

</Location>

230

</LocationProvider>

231

);

232

};

233

234

// Multiple context consumers

235

const MultiContextComponent = () => (

236

<UserContext.Consumer>

237

{(user) => (

238

<ThemeContext.Consumer>

239

{(theme) => (

240

<Location>

241

{({ location, navigate }) => (

242

<div className={theme.className}>

243

<p>User: {user.name}</p>

244

<p>Path: {location.pathname}</p>

245

<button onClick={() => navigate("/profile")}>

246

Profile

247

</button>

248

</div>

249

)}

250

</Location>

251

)}

252

</ThemeContext.Consumer>

253

)}

254

</UserContext.Consumer>

255

);

256

```

257

258

### Location Context State Management

259

260

Understanding how location context manages state and updates.

261

262

```javascript { .api }

263

/**

264

* Location context state management

265

*/

266

interface LocationContextBehavior {

267

// Context updates when:

268

// - Browser navigation (back/forward)

269

// - Programmatic navigation via navigate()

270

// - URL changes from external sources

271

272

// Context provides:

273

// - Current location object

274

// - Navigation function

275

// - Automatic re-rendering on location changes

276

}

277

```

278

279

**Usage Examples:**

280

281

```javascript

282

// Listening to location changes

283

const LocationLogger = () => {

284

const [history, setHistory] = React.useState([]);

285

286

return (

287

<Location>

288

{({ location }) => {

289

React.useEffect(() => {

290

setHistory(prev => [

291

...prev,

292

{ pathname: location.pathname, timestamp: Date.now() }

293

]);

294

}, [location.pathname]);

295

296

return (

297

<div>

298

<h3>Navigation History</h3>

299

{history.map((entry, index) => (

300

<div key={index}>

301

{entry.pathname} at {new Date(entry.timestamp).toLocaleTimeString()}

302

</div>

303

))}

304

</div>

305

);

306

}}

307

</Location>

308

);

309

};

310

311

// Persisting location state

312

const LocationPersistence = () => (

313

<Location>

314

{({ location }) => {

315

React.useEffect(() => {

316

localStorage.setItem("lastLocation", location.pathname);

317

}, [location.pathname]);

318

319

return <div>Location saved to localStorage</div>;

320

}}

321

</Location>

322

);

323

324

// Conditional effects based on location

325

const LocationEffects = () => (

326

<Location>

327

{({ location }) => {

328

React.useEffect(() => {

329

// Track page views

330

analytics.track("pageview", { path: location.pathname });

331

}, [location.pathname]);

332

333

React.useEffect(() => {

334

// Update document title

335

const titles = {

336

"/": "Home",

337

"/about": "About Us",

338

"/contact": "Contact"

339

};

340

document.title = titles[location.pathname] || "Page";

341

}, [location.pathname]);

342

343

return null;

344

}}

345

</Location>

346

);

347

348

// Error boundaries with location context

349

class LocationErrorBoundary extends React.Component {

350

constructor(props) {

351

super(props);

352

this.state = { hasError: false, errorLocation: null };

353

}

354

355

static getDerivedStateFromError(error) {

356

return { hasError: true };

357

}

358

359

componentDidCatch(error, errorInfo) {

360

console.error("Error at location:", this.state.errorLocation);

361

}

362

363

render() {

364

if (this.state.hasError) {

365

return (

366

<Location>

367

{({ location, navigate }) => (

368

<div>

369

<h2>Something went wrong at {location.pathname}</h2>

370

<button onClick={() => navigate("/")}>Go Home</button>

371

</div>

372

)}

373

</Location>

374

);

375

}

376

377

return (

378

<Location>

379

{({ location }) => {

380

this.state.errorLocation = location.pathname;

381

return this.props.children;

382

}}

383

</Location>

384

);

385

}

386

}

387

```