react-native-design

安装量: 9.5K
排名: #820

安装

npx skills add https://github.com/wshobson/agents --skill react-native-design
React Native Design
Master React Native styling patterns, React Navigation, and Reanimated 3 to build performant, cross-platform mobile applications with native-quality user experiences.
When to Use This Skill
Building cross-platform mobile apps with React Native
Implementing navigation with React Navigation 6+
Creating performant animations with Reanimated 3
Styling components with StyleSheet and styled-components
Building responsive layouts for different screen sizes
Implementing platform-specific designs (iOS/Android)
Creating gesture-driven interactions with Gesture Handler
Optimizing React Native performance
Core Concepts
1. StyleSheet and Styling
Basic StyleSheet:
import
{
StyleSheet
,
View
,
Text
}
from
'react-native'
;
const
styles
=
StyleSheet
.
create
(
{
container
:
{
flex
:
1
,
padding
:
16
,
backgroundColor
:
'#ffffff'
,
}
,
title
:
{
fontSize
:
24
,
fontWeight
:
'600'
,
color
:
'#1a1a1a'
,
marginBottom
:
8
,
}
,
subtitle
:
{
fontSize
:
16
,
color
:
'#666666'
,
lineHeight
:
24
,
}
,
}
)
;
function
Card
(
)
{
return
(
<
View style
=
{
styles
.
container
}
>
<
Text style
=
{
styles
.
title
}
>
Title
<
/
Text
>
<
Text style
=
{
styles
.
subtitle
}
>
Subtitle text
<
/
Text
>
<
/
View
>
)
;
}
Dynamic Styles:
interface
CardProps
{
variant
:
'primary'
|
'secondary'
;
disabled
?
:
boolean
;
}
function
Card
(
{
variant
,
disabled
}
:
CardProps
)
{
return
(
<
View style
=
{
[
styles
.
card
,
variant
===
'primary'
?
styles
.
primary
:
styles
.
secondary
,
disabled
&&
styles
.
disabled
,
]
}
>
<
Text style
=
{
styles
.
text
}
>
Content
<
/
Text
>
<
/
View
>
)
;
}
const
styles
=
StyleSheet
.
create
(
{
card
:
{
padding
:
16
,
borderRadius
:
12
,
}
,
primary
:
{
backgroundColor
:
'#6366f1'
,
}
,
secondary
:
{
backgroundColor
:
'#f3f4f6'
,
borderWidth
:
1
,
borderColor
:
'#e5e7eb'
,
}
,
disabled
:
{
opacity
:
0.5
,
}
,
text
:
{
fontSize
:
16
,
}
,
}
)
;
2. Flexbox Layout
Row and Column Layouts:
const
styles
=
StyleSheet
.
create
(
{
// Vertical stack (column)
column
:
{
flexDirection
:
"column"
,
gap
:
12
,
}
,
// Horizontal stack (row)
row
:
{
flexDirection
:
"row"
,
alignItems
:
"center"
,
gap
:
8
,
}
,
// Space between items
spaceBetween
:
{
flexDirection
:
"row"
,
justifyContent
:
"space-between"
,
alignItems
:
"center"
,
}
,
// Centered content
centered
:
{
flex
:
1
,
justifyContent
:
"center"
,
alignItems
:
"center"
,
}
,
// Fill remaining space
fill
:
{
flex
:
1
,
}
,
}
)
;
3. React Navigation Setup
Stack Navigator:
import
{
NavigationContainer
}
from
'@react-navigation/native'
;
import
{
createNativeStackNavigator
}
from
'@react-navigation/native-stack'
;
type
RootStackParamList
=
{
Home
:
undefined
;
Detail
:
{
itemId
:
string
}
;
Settings
:
undefined
;
}
;
const
Stack
=
createNativeStackNavigator
<
RootStackParamList
>
(
)
;
function
AppNavigator
(
)
{
return
(
<
NavigationContainer
>
<
Stack
.
Navigator
initialRouteName
=
"Home"
screenOptions
=
{
{
headerStyle
:
{
backgroundColor
:
'#6366f1'
}
,
headerTintColor
:
'#ffffff'
,
headerTitleStyle
:
{
fontWeight
:
'600'
}
,
}
}
>
<
Stack
.
Screen
name
=
"Home"
component
=
{
HomeScreen
}
options
=
{
{
title
:
'Home'
}
}
/
>
<
Stack
.
Screen
name
=
"Detail"
component
=
{
DetailScreen
}
options
=
{
(
{
route
}
)
=>
(
{
title
:
`
Item
${
route
.
params
.
itemId
}
`
,
}
)
}
/
>
<
Stack
.
Screen name
=
"Settings"
component
=
{
SettingsScreen
}
/
>
<
/
Stack
.
Navigator
>
<
/
NavigationContainer
>
)
;
}
Tab Navigator:
import
{
createBottomTabNavigator
}
from
'@react-navigation/bottom-tabs'
;
import
{
Ionicons
}
from
'@expo/vector-icons'
;
type
TabParamList
=
{
Home
:
undefined
;
Search
:
undefined
;
Profile
:
undefined
;
}
;
const
Tab
=
createBottomTabNavigator
<
TabParamList
>
(
)
;
function
TabNavigator
(
)
{
return
(
<
Tab
.
Navigator
screenOptions
=
{
(
{
route
}
)
=>
(
{
tabBarIcon
:
(
{
focused
,
color
,
size
}
)
=>
{
const
icons
:
Record
<
string
,
keyof
typeof
Ionicons
.
glyphMap
>
=
{
Home
:
focused
?
'home'
:
'home-outline'
,
Search
:
focused
?
'search'
:
'search-outline'
,
Profile
:
focused
?
'person'
:
'person-outline'
,
}
;
return
<
Ionicons name
=
{
icons
[
route
.
name
]
}
size
=
{
size
}
color
=
{
color
}
/
>
;
}
,
tabBarActiveTintColor
:
'#6366f1'
,
tabBarInactiveTintColor
:
'#9ca3af'
,
}
)
}
>
<
Tab
.
Screen name
=
"Home"
component
=
{
HomeScreen
}
/
>
<
Tab
.
Screen name
=
"Search"
component
=
{
SearchScreen
}
/
>
<
Tab
.
Screen name
=
"Profile"
component
=
{
ProfileScreen
}
/
>
<
/
Tab
.
Navigator
>
)
;
}
4. Reanimated 3 Basics
Animated Values:
import
Animated
,
{
useSharedValue
,
useAnimatedStyle
,
withSpring
,
withTiming
,
}
from
'react-native-reanimated'
;
function
AnimatedBox
(
)
{
const
scale
=
useSharedValue
(
1
)
;
const
opacity
=
useSharedValue
(
1
)
;
const
animatedStyle
=
useAnimatedStyle
(
(
)
=>
(
{
transform
:
[
{
scale
:
scale
.
value
}
]
,
opacity
:
opacity
.
value
,
}
)
)
;
const
handlePress
=
(
)
=>
{
scale
.
value
=
withSpring
(
1.2
,
{
}
,
(
)
=>
{
scale
.
value
=
withSpring
(
1
)
;
}
)
;
}
;
return
(
<
Pressable onPress
=
{
handlePress
}
>
<
Animated
.
View style
=
{
[
styles
.
box
,
animatedStyle
]
}
/
>
<
/
Pressable
>
)
;
}
Gesture Handler Integration:
import
{
Gesture
,
GestureDetector
}
from
'react-native-gesture-handler'
;
import
Animated
,
{
useSharedValue
,
useAnimatedStyle
,
withSpring
,
}
from
'react-native-reanimated'
;
function
DraggableCard
(
)
{
const
translateX
=
useSharedValue
(
0
)
;
const
translateY
=
useSharedValue
(
0
)
;
const
gesture
=
Gesture
.
Pan
(
)
.
onUpdate
(
(
event
)
=>
{
translateX
.
value
=
event
.
translationX
;
translateY
.
value
=
event
.
translationY
;
}
)
.
onEnd
(
(
)
=>
{
translateX
.
value
=
withSpring
(
0
)
;
translateY
.
value
=
withSpring
(
0
)
;
}
)
;
const
animatedStyle
=
useAnimatedStyle
(
(
)
=>
(
{
transform
:
[
{
translateX
:
translateX
.
value
}
,
{
translateY
:
translateY
.
value
}
,
]
,
}
)
)
;
return
(
<
GestureDetector gesture
=
{
gesture
}
>
<
Animated
.
View style
=
{
[
styles
.
card
,
animatedStyle
]
}
>
<
Text
>
Drag me
!
<
/
Text
>
<
/
Animated
.
View
>
<
/
GestureDetector
>
)
;
}
5. Platform-Specific Styling
import
{
Platform
,
StyleSheet
}
from
"react-native"
;
const
styles
=
StyleSheet
.
create
(
{
container
:
{
padding
:
16
,
...
Platform
.
select
(
{
ios
:
{
shadowColor
:
"#000"
,
shadowOffset
:
{
width
:
0
,
height
:
2
}
,
shadowOpacity
:
0.1
,
shadowRadius
:
4
,
}
,
android
:
{
elevation
:
4
,
}
,
}
)
,
}
,
text
:
{
fontFamily
:
Platform
.
OS
===
"ios"
?
"SF Pro Text"
:
"Roboto"
,
fontSize
:
16
,
}
,
}
)
;
// Platform-specific components
import
{
Platform
}
from
"react-native"
;
const
StatusBarHeight
=
Platform
.
OS
===
"ios"
?
44
:
0
;
Quick Start Component
import
React
from
'react'
;
import
{
View
,
Text
,
StyleSheet
,
Pressable
,
Image
,
}
from
'react-native'
;
import
Animated
,
{
useSharedValue
,
useAnimatedStyle
,
withSpring
,
}
from
'react-native-reanimated'
;
interface
ItemCardProps
{
title
:
string
;
subtitle
:
string
;
imageUrl
:
string
;
onPress
:
(
)
=>
void
;
}
const
AnimatedPressable
=
Animated
.
createAnimatedComponent
(
Pressable
)
;
export
function
ItemCard
(
{
title
,
subtitle
,
imageUrl
,
onPress
}
:
ItemCardProps
)
{
const
scale
=
useSharedValue
(
1
)
;
const
animatedStyle
=
useAnimatedStyle
(
(
)
=>
(
{
transform
:
[
{
scale
:
scale
.
value
}
]
,
}
)
)
;
return
(
<
AnimatedPressable
style
=
{
[
styles
.
card
,
animatedStyle
]
}
onPress
=
{
onPress
}
onPressIn
=
{
(
)
=>
{
scale
.
value
=
withSpring
(
0.97
)
;
}
}
onPressOut
=
{
(
)
=>
{
scale
.
value
=
withSpring
(
1
)
;
}
}
>
<
Image source
=
{
{
uri
:
imageUrl
}
}
style
=
{
styles
.
image
}
/
>
<
View style
=
{
styles
.
content
}
>
<
Text style
=
{
styles
.
title
}
numberOfLines
=
{
1
}
>
{
title
}
<
/
Text
>
<
Text style
=
{
styles
.
subtitle
}
numberOfLines
=
{
2
}
>
{
subtitle
}
<
/
Text
>
<
/
View
>
<
/
AnimatedPressable
>
)
;
}
const
styles
=
StyleSheet
.
create
(
{
card
:
{
backgroundColor
:
'#ffffff'
,
borderRadius
:
16
,
overflow
:
'hidden'
,
shadowColor
:
'#000'
,
shadowOffset
:
{
width
:
0
,
height
:
2
}
,
shadowOpacity
:
0.1
,
shadowRadius
:
8
,
elevation
:
4
,
}
,
image
:
{
width
:
'100%'
,
height
:
160
,
backgroundColor
:
'#f3f4f6'
,
}
,
content
:
{
padding
:
16
,
gap
:
4
,
}
,
title
:
{
fontSize
:
18
,
fontWeight
:
'600'
,
color
:
'#1f2937'
,
}
,
subtitle
:
{
fontSize
:
14
,
color
:
'#6b7280'
,
lineHeight
:
20
,
}
,
}
)
;
Best Practices
Use TypeScript
Define navigation and prop types for type safety
Memoize Components
Use
React.memo
and
useCallback
to prevent unnecessary rerenders
Run Animations on UI Thread
Use Reanimated worklets for 60fps animations
Avoid Inline Styles
Use StyleSheet.create for performance
Handle Safe Areas
Use
SafeAreaView
or
useSafeAreaInsets
Test on Real Devices
Simulator/emulator performance differs from real devices
Use FlatList for Lists
Never use ScrollView with map for long lists
Platform-Specific Code
Use Platform.select for iOS/Android differences
Common Issues
Gesture Conflicts
Wrap gestures with
GestureDetector
and use
simultaneousHandlers
Navigation Type Errors
Define
ParamList
types for all navigators
Animation Jank
Move animations to UI thread with
runOnUI
worklets
Memory Leaks
Cancel animations and cleanup in useEffect
Font Loading
Use
expo-font
or
react-native-asset
for custom fonts
Safe Area Issues
Test on notched devices (iPhone, Android with cutouts)
返回排行榜