or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animations.mdcolors.mdcomponents.mdcoordinates.mdindex.mdmath.mdmatrices.mdpaths.mdtransforms.mdtransitions.mdutilities.mdvectors.md

transitions.mddocs/

0

# Transition Hooks

1

2

React hooks for creating smooth transitions with spring and timing animations, providing convenient wrappers around React Native Reanimated's animation functions.

3

4

```typescript

5

import type { WithSpringConfig, WithTimingConfig } from "react-native-reanimated";

6

```

7

8

## Capabilities

9

10

### Spring Transitions

11

12

Create spring-based transitions that respond to state changes with natural, physics-based motion.

13

14

```typescript { .api }

15

/**

16

* Create spring transition based on state

17

* @param state - Boolean or numeric state to animate

18

* @param config - Optional spring configuration

19

* @returns Animated value that springs to target

20

*/

21

function useSpring(

22

state: boolean | number,

23

config?: WithSpringConfig

24

): Animated.DerivedValue<number>;

25

```

26

27

**Usage Example:**

28

29

```typescript

30

import { useSpring } from "react-native-redash";

31

import { useAnimatedStyle } from "react-native-reanimated";

32

import { useState } from "react";

33

34

export const SpringButton = () => {

35

const [isPressed, setIsPressed] = useState(false);

36

37

// Spring animation for scale

38

const scale = useSpring(isPressed, {

39

damping: 15,

40

stiffness: 200,

41

mass: 1

42

});

43

44

const animatedStyle = useAnimatedStyle(() => ({

45

transform: [{ scale: scale.value }]

46

}));

47

48

return (

49

<Animated.View

50

style={[{ width: 100, height: 100, backgroundColor: 'blue' }, animatedStyle]}

51

onTouchStart={() => setIsPressed(true)}

52

onTouchEnd={() => setIsPressed(false)}

53

/>

54

);

55

};

56

```

57

58

### Timing Transitions

59

60

Create timing-based transitions with customizable duration and easing curves.

61

62

```typescript { .api }

63

/**

64

* Create timing transition based on state

65

* @param state - Boolean or numeric state to animate

66

* @param config - Optional timing configuration

67

* @returns Animated value that times to target

68

*/

69

function useTiming(

70

state: boolean | number,

71

config?: WithTimingConfig

72

): Animated.DerivedValue<number>;

73

```

74

75

**Usage Example:**

76

77

```typescript

78

import { useTiming } from "react-native-redash";

79

import { useAnimatedStyle } from "react-native-reanimated";

80

import { Easing } from "react-native-reanimated";

81

import { useState } from "react";

82

83

export const TimingTransition = () => {

84

const [isVisible, setIsVisible] = useState(false);

85

86

// Timing animation for opacity

87

const opacity = useTiming(isVisible, {

88

duration: 300,

89

easing: Easing.inOut(Easing.ease)

90

});

91

92

// Timing animation for position

93

const translateY = useTiming(isVisible ? 0 : 100, {

94

duration: 500,

95

easing: Easing.out(Easing.cubic)

96

});

97

98

const animatedStyle = useAnimatedStyle(() => ({

99

opacity: opacity.value,

100

transform: [{ translateY: translateY.value }]

101

}));

102

103

return (

104

<>

105

<TouchableOpacity onPress={() => setIsVisible(!isVisible)}>

106

<Text>Toggle</Text>

107

</TouchableOpacity>

108

109

<Animated.View

110

style={[

111

{ width: 100, height: 100, backgroundColor: 'red' },

112

animatedStyle

113

]}

114

/>

115

</>

116

);

117

};

118

```

119

120

### Numeric State Transitions

121

122

Both hooks work with numeric values, not just booleans.

123

124

```typescript

125

import { useSpring, useTiming } from "react-native-redash";

126

import { useState } from "react";

127

128

export const NumericTransitions = () => {

129

const [value, setValue] = useState(0);

130

131

// Spring to numeric value

132

const springValue = useSpring(value * 100, {

133

damping: 20,

134

stiffness: 100

135

});

136

137

// Timing to numeric value

138

const timingValue = useTiming(value * 200, {

139

duration: 1000

140

});

141

142

const animatedStyle = useAnimatedStyle(() => ({

143

transform: [

144

{ translateX: springValue.value },

145

{ translateY: timingValue.value }

146

]

147

}));

148

149

return (

150

<View>

151

<Slider

152

value={value}

153

onValueChange={setValue}

154

minimumValue={0}

155

maximumValue={1}

156

/>

157

<Animated.View style={[styles.box, animatedStyle]} />

158

</View>

159

);

160

};

161

```

162

163

### Complex State-Based Animations

164

165

Combine multiple transition hooks for complex animations.

166

167

```typescript

168

import { useSpring, useTiming } from "react-native-redash";

169

import { useState, useEffect } from "react";

170

171

export const ComplexTransition = () => {

172

const [currentTab, setCurrentTab] = useState(0);

173

const [isLoading, setIsLoading] = useState(false);

174

175

// Spring animation for tab indicator

176

const tabPosition = useSpring(currentTab * 100, {

177

damping: 25,

178

stiffness: 300

179

});

180

181

// Timing animation for loading state

182

const loadingOpacity = useTiming(isLoading, {

183

duration: 200

184

});

185

186

// Spring animation for content scale

187

const contentScale = useSpring(isLoading ? 0.95 : 1, {

188

damping: 20,

189

stiffness: 200

190

});

191

192

const tabIndicatorStyle = useAnimatedStyle(() => ({

193

transform: [{ translateX: tabPosition.value }]

194

}));

195

196

const contentStyle = useAnimatedStyle(() => ({

197

opacity: 1 - loadingOpacity.value * 0.5,

198

transform: [{ scale: contentScale.value }]

199

}));

200

201

const loadingStyle = useAnimatedStyle(() => ({

202

opacity: loadingOpacity.value

203

}));

204

205

return (

206

<View>

207

{/* Tab Indicator */}

208

<Animated.View style={[styles.tabIndicator, tabIndicatorStyle]} />

209

210

{/* Content */}

211

<Animated.View style={[styles.content, contentStyle]}>

212

{/* Content here */}

213

</Animated.View>

214

215

{/* Loading Overlay */}

216

<Animated.View style={[styles.loadingOverlay, loadingStyle]}>

217

<ActivityIndicator />

218

</Animated.View>

219

</View>

220

);

221

};

222

```

223

224

### Performance Considerations

225

226

Both hooks automatically handle state changes and create smooth transitions:

227

228

```typescript

229

import { useSpring } from "react-native-redash";

230

import { useState, useCallback } from "react";

231

232

export const PerformantComponent = () => {

233

const [count, setCount] = useState(0);

234

235

// Automatically animates when count changes

236

const animatedCount = useSpring(count, {

237

damping: 15,

238

stiffness: 100

239

});

240

241

// Memoize handlers to prevent unnecessary re-renders

242

const increment = useCallback(() => {

243

setCount(prev => prev + 1);

244

}, []);

245

246

const animatedStyle = useAnimatedStyle(() => ({

247

transform: [

248

{ scale: 1 + animatedCount.value * 0.1 },

249

{ rotate: `${animatedCount.value * 10}deg` }

250

]

251

}));

252

253

return (

254

<TouchableOpacity onPress={increment}>

255

<Animated.View style={[styles.counter, animatedStyle]}>

256

<Text>{count}</Text>

257

</Animated.View>

258

</TouchableOpacity>

259

);

260

};

261

```

262

263

**Configuration Options:**

264

265

The hooks accept the same configuration options as React Native Reanimated's `withSpring` and `withTiming`. These types are imported from `react-native-reanimated`:

266

267

**WithSpringConfig:**

268

- `damping?: number` - Damping coefficient (default: 10)

269

- `mass?: number` - Mass of the object (default: 1)

270

- `stiffness?: number` - Spring stiffness (default: 100)

271

- `overshootClamping?: boolean` - Prevent overshooting (default: false)

272

- `restDisplacementThreshold?: number` - Threshold for rest detection (default: 0.01)

273

- `restSpeedThreshold?: number` - Speed threshold for rest detection (default: 2)

274

275

**WithTimingConfig:**

276

- `duration?: number` - Animation duration in milliseconds (default: 300)

277

- `easing?: EasingFunction` - Easing function from react-native-reanimated (default: Easing.inOut(Easing.quad))

278

279

**Best Practices:**

280

281

1. Use `useSpring` for interactive elements (buttons, toggles, gestures)

282

2. Use `useTiming` for sequential animations or precise timing control

283

3. Combine both for rich, layered animations

284

4. Keep configuration objects stable to avoid unnecessary re-animations

285

5. Use numeric states for smooth value transitions

286

6. Boolean states automatically convert to 0/1 for animations