or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

connect.mdhooks.mdindex.mdtypescript.md

connect.mddocs/

0

# Connect Higher-Order Component

1

2

Legacy API for connecting React components to Redux store using higher-order component pattern. While hooks are the recommended modern approach, connect remains fully supported for class components and complex scenarios.

3

4

## Capabilities

5

6

### Connect Function

7

8

Higher-order component factory that connects React components to Redux store by injecting state and dispatch as props.

9

10

```typescript { .api }

11

/**

12

* Connect function overloads for different usage patterns

13

*/

14

interface Connect<DefaultState = unknown> {

15

// No arguments - just adds dispatch prop

16

(): InferableComponentEnhancer<DispatchProp>;

17

18

// mapStateToProps only

19

<TStateProps = {}, no_dispatch = {}, TOwnProps = {}, State = DefaultState>(

20

mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>

21

): InferableComponentEnhancerWithProps<TStateProps & DispatchProp, TOwnProps>;

22

23

// mapDispatchToProps only (function)

24

<no_state = {}, TDispatchProps = {}, TOwnProps = {}>(

25

mapStateToProps: null | undefined,

26

mapDispatchToProps: MapDispatchToPropsFunction<TDispatchProps, TOwnProps>

27

): InferableComponentEnhancerWithProps<TDispatchProps, TOwnProps>;

28

29

// mapDispatchToProps only (object)

30

<no_state = {}, TDispatchProps = {}, TOwnProps = {}>(

31

mapStateToProps: null | undefined,

32

mapDispatchToProps: MapDispatchToPropsParam<TDispatchProps, TOwnProps>

33

): InferableComponentEnhancerWithProps<ResolveThunks<TDispatchProps>, TOwnProps>;

34

35

// Both mapStateToProps and mapDispatchToProps (function)

36

<TStateProps = {}, TDispatchProps = {}, TOwnProps = {}, State = DefaultState>(

37

mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,

38

mapDispatchToProps: MapDispatchToPropsFunction<TDispatchProps, TOwnProps>

39

): InferableComponentEnhancerWithProps<TStateProps & TDispatchProps, TOwnProps>;

40

41

// Both mapStateToProps and mapDispatchToProps (object)

42

<TStateProps = {}, TDispatchProps = {}, TOwnProps = {}, State = DefaultState>(

43

mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,

44

mapDispatchToProps: MapDispatchToPropsParam<TDispatchProps, TOwnProps>

45

): InferableComponentEnhancerWithProps<TStateProps & ResolveThunks<TDispatchProps>, TOwnProps>;

46

47

// All three arguments

48

<TStateProps = {}, TDispatchProps = {}, TOwnProps = {}, TMergedProps = {}, State = DefaultState>(

49

mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,

50

mapDispatchToProps: MapDispatchToPropsParam<TDispatchProps, TOwnProps>,

51

mergeProps: MergeProps<TStateProps, TDispatchProps, TOwnProps, TMergedProps>

52

): InferableComponentEnhancerWithProps<TMergedProps, TOwnProps>;

53

54

// All four arguments

55

<TStateProps = {}, TDispatchProps = {}, TOwnProps = {}, TMergedProps = {}, State = DefaultState>(

56

mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,

57

mapDispatchToProps: MapDispatchToPropsParam<TDispatchProps, TOwnProps>,

58

mergeProps: MergeProps<TStateProps, TDispatchProps, TOwnProps, TMergedProps>,

59

options: ConnectOptions<State, TStateProps, TOwnProps, TMergedProps>

60

): InferableComponentEnhancerWithProps<TMergedProps, TOwnProps>;

61

}

62

63

const connect: Connect;

64

65

type InferableComponentEnhancer<TInjectedProps> =

66

InferableComponentEnhancerWithProps<TInjectedProps, {}>;

67

68

type InferableComponentEnhancerWithProps<TInjectedProps, TNeedsProps> =

69

<C extends ComponentType<Matching<TInjectedProps, GetProps<C>>>>(

70

component: C

71

) => ConnectedComponent<C, Mapped<DistributiveOmit<GetLibraryManagedProps<C>, keyof Shared<TInjectedProps, GetLibraryManagedProps<C>>> & TNeedsProps & ConnectPropsMaybeWithoutContext<TNeedsProps & GetProps<C>>>>;

72

73

type ConnectedComponent<C extends ComponentType<any>, P> =

74

FunctionComponent<P> & NonReactStatics<C> & { WrappedComponent: C };

75

```

76

77

**Basic Usage:**

78

79

```typescript

80

import { connect } from "react-redux";

81

82

// Class component

83

class TodoList extends Component<Props> {

84

render() {

85

const { todos, addTodo } = this.props;

86

return (

87

<div>

88

{todos.map(todo => <div key={todo.id}>{todo.text}</div>)}

89

<button onClick={() => addTodo("New todo")}>Add</button>

90

</div>

91

);

92

}

93

}

94

95

// Connect to Redux

96

const mapStateToProps = (state: RootState) => ({

97

todos: state.todos

98

});

99

100

const mapDispatchToProps = {

101

addTodo: (text: string) => ({ type: "ADD_TODO", payload: text })

102

};

103

104

export default connect(mapStateToProps, mapDispatchToProps)(TodoList);

105

```

106

107

### Map State to Props

108

109

Functions that define how Redux state maps to component props.

110

111

```typescript { .api }

112

/**

113

* Function that maps Redux state to component props

114

*/

115

type MapStateToProps<TStateProps, TOwnProps, State> =

116

(state: State, ownProps: TOwnProps) => TStateProps;

117

118

/**

119

* Factory function that creates a mapStateToProps function

120

*/

121

type MapStateToPropsFactory<TStateProps, TOwnProps, State> =

122

(initialState: State, ownProps: TOwnProps) => MapStateToProps<TStateProps, TOwnProps, State>;

123

124

/**

125

* Parameter type for mapStateToProps - can be function or factory

126

*/

127

type MapStateToPropsParam<TStateProps, TOwnProps, State> =

128

MapStateToPropsFactory<TStateProps, TOwnProps, State> |

129

MapStateToProps<TStateProps, TOwnProps, State> |

130

null |

131

undefined;

132

```

133

134

**Usage Examples:**

135

136

```typescript

137

// Simple state mapping

138

const mapStateToProps = (state: RootState) => ({

139

user: state.auth.user,

140

isLoading: state.ui.loading

141

});

142

143

// With own props

144

const mapStateToProps = (state: RootState, ownProps: OwnProps) => ({

145

todo: state.todos.find(todo => todo.id === ownProps.todoId)

146

});

147

148

// Factory function for performance optimization

149

const makeMapStateToProps = () => {

150

const getTodosForUser = createSelector(

151

[(state: RootState) => state.todos, (state: RootState, props: Props) => props.userId],

152

(todos, userId) => todos.filter(todo => todo.userId === userId)

153

);

154

155

return (state: RootState, props: Props) => ({

156

todos: getTodosForUser(state, props)

157

});

158

};

159

```

160

161

### Map Dispatch to Props

162

163

Functions and objects that define how dispatch maps to component props.

164

165

```typescript { .api }

166

/**

167

* Function that maps dispatch to component props

168

*/

169

type MapDispatchToPropsFunction<TDispatchProps, TOwnProps> =

170

(dispatch: Dispatch<Action<string>>, ownProps: TOwnProps) => TDispatchProps;

171

172

/**

173

* Object mapping action creators to component props

174

*/

175

type MapDispatchToProps<TDispatchProps, TOwnProps> =

176

MapDispatchToPropsFunction<TDispatchProps, TOwnProps> | TDispatchProps;

177

178

/**

179

* Factory function that creates a mapDispatchToProps function

180

*/

181

type MapDispatchToPropsFactory<TDispatchProps, TOwnProps> =

182

(dispatch: Dispatch<Action<string>>, ownProps: TOwnProps) => MapDispatchToPropsFunction<TDispatchProps, TOwnProps>;

183

184

/**

185

* Parameter type for mapDispatchToProps

186

*/

187

type MapDispatchToPropsParam<TDispatchProps, TOwnProps> =

188

MapDispatchToPropsFactory<TDispatchProps, TOwnProps> |

189

MapDispatchToProps<TDispatchProps, TOwnProps>;

190

191

/**

192

* Resolves thunk action creators in dispatch props

193

*/

194

type ResolveThunks<TDispatchProps> = TDispatchProps extends { [key: string]: any }

195

? { [C in keyof TDispatchProps]: HandleThunkActionCreator<TDispatchProps[C]> }

196

: TDispatchProps;

197

```

198

199

**Usage Examples:**

200

201

```typescript

202

// Object shorthand (recommended)

203

const mapDispatchToProps = {

204

addTodo: (text: string) => ({ type: "ADD_TODO", payload: text }),

205

removeTodo: (id: number) => ({ type: "REMOVE_TODO", payload: id })

206

};

207

208

// Function form

209

const mapDispatchToProps = (dispatch: Dispatch) => ({

210

addTodo: (text: string) => dispatch({ type: "ADD_TODO", payload: text }),

211

removeTodo: (id: number) => dispatch({ type: "REMOVE_TODO", payload: id })

212

});

213

214

// With thunk actions

215

const mapDispatchToProps = {

216

fetchUser: fetchUserThunk,

217

updateUser: updateUserThunk

218

};

219

220

// Factory function

221

const makeMapDispatchToProps = () => {

222

return (dispatch: Dispatch, ownProps: Props) => ({

223

loadData: () => dispatch(fetchData(ownProps.dataId))

224

});

225

};

226

```

227

228

### Merge Props

229

230

Function that combines state props, dispatch props, and own props into final props.

231

232

```typescript { .api }

233

/**

234

* Function that merges state props, dispatch props, and own props

235

* @param stateProps - Props from mapStateToProps

236

* @param dispatchProps - Props from mapDispatchToProps

237

* @param ownProps - Props passed to the connected component

238

* @returns Final props object for the wrapped component

239

*/

240

type MergeProps<TStateProps, TDispatchProps, TOwnProps, TMergedProps> =

241

(stateProps: TStateProps, dispatchProps: TDispatchProps, ownProps: TOwnProps) => TMergedProps;

242

```

243

244

**Usage Example:**

245

246

```typescript

247

const mergeProps = (stateProps, dispatchProps, ownProps) => ({

248

...stateProps,

249

...dispatchProps,

250

...ownProps,

251

// Custom merged prop

252

canEdit: stateProps.user.id === ownProps.itemOwnerId && stateProps.user.isLoggedIn

253

});

254

255

const ConnectedComponent = connect(

256

mapStateToProps,

257

mapDispatchToProps,

258

mergeProps

259

)(MyComponent);

260

```

261

262

### Connect Options

263

264

Configuration options for customizing connect behavior.

265

266

```typescript { .api }

267

interface ConnectOptions<State = unknown, TStateProps = {}, TOwnProps = {}, TMergedProps = {}> {

268

/** Enable ref forwarding to wrapped component */

269

forwardRef?: boolean;

270

/** Custom context to use instead of ReactReduxContext */

271

context?: typeof ReactReduxContext;

272

/** Custom equality function for state comparison */

273

areStatesEqual?: (nextState: State, prevState: State, nextOwnProps: TOwnProps, prevOwnProps: TOwnProps) => boolean;

274

/** Custom equality function for own props comparison */

275

areOwnPropsEqual?: (nextOwnProps: TOwnProps, prevOwnProps: TOwnProps) => boolean;

276

/** Custom equality function for state props comparison */

277

areStatePropsEqual?: (nextStateProps: TStateProps, prevStateProps: TStateProps) => boolean;

278

/** Custom equality function for merged props comparison */

279

areMergedPropsEqual?: (nextMergedProps: TMergedProps, prevMergedProps: TMergedProps) => boolean;

280

}

281

```

282

283

**Usage Example:**

284

285

```typescript

286

const options = {

287

forwardRef: true,

288

areStatesEqual: (next, prev) => next.version === prev.version,

289

areOwnPropsEqual: (next, prev) => next.id === prev.id

290

};

291

292

const ConnectedComponent = connect(

293

mapStateToProps,

294

mapDispatchToProps,

295

null,

296

options

297

)(MyComponent);

298

299

// Access original component through ref

300

const ref = useRef();

301

<ConnectedComponent ref={ref} />

302

// ref.current points to MyComponent instance

303

```

304

305

## Advanced Usage

306

307

### ConnectedProps Type Helper

308

309

Extract props type from a connected component for type reuse.

310

311

```typescript { .api }

312

/**

313

* Extracts the props type from a connected component

314

*/

315

type ConnectedProps<TConnector> = TConnector extends InferableComponentEnhancerWithProps<infer TInjectedProps, any>

316

? unknown extends TInjectedProps

317

? TConnector extends InferableComponentEnhancer<infer TInjectedProps>

318

? TInjectedProps

319

: never

320

: TInjectedProps

321

: never;

322

```

323

324

**Usage Example:**

325

326

```typescript

327

const connector = connect(mapStateToProps, mapDispatchToProps);

328

type PropsFromRedux = ConnectedProps<typeof connector>;

329

330

// Use in component definition

331

const MyComponent: React.FC<PropsFromRedux & OwnProps> = (props) => {

332

// props includes both Redux and own props

333

};

334

335

export default connector(MyComponent);

336

```

337

338

### Custom Context Usage

339

340

Use connect with custom React context for multiple stores.

341

342

```typescript

343

import { createContext } from "react";

344

import { connect } from "react-redux";

345

346

const CustomContext = createContext(null);

347

348

const ConnectedComponent = connect(

349

mapStateToProps,

350

mapDispatchToProps,

351

null,

352

{ context: CustomContext }

353

)(MyComponent);

354

355

// Provide custom context

356

<Provider store={customStore} context={CustomContext}>

357

<ConnectedComponent />

358

</Provider>

359

```

360

361

## Migration from Connect to Hooks

362

363

While connect is fully supported, hooks provide a more modern and flexible API:

364

365

```typescript

366

// Connect approach

367

const mapStateToProps = (state: RootState) => ({

368

todos: state.todos,

369

user: state.user

370

});

371

372

const mapDispatchToProps = {

373

addTodo,

374

removeUser

375

};

376

377

export default connect(mapStateToProps, mapDispatchToProps)(TodoList);

378

379

// Hooks approach

380

function TodoList() {

381

const todos = useSelector((state: RootState) => state.todos);

382

const user = useSelector((state: RootState) => state.user);

383

const dispatch = useDispatch();

384

385

const handleAddTodo = (text: string) => dispatch(addTodo(text));

386

const handleRemoveUser = (id: number) => dispatch(removeUser(id));

387

388

return (

389

// Component JSX

390

);

391

}

392

```