Q&A
How to customize a button in NativeBase
Overview
NativeBase is a React Native (and web) UI library with a themeable component system. Its Button is highly configurable: most visual tweaks are just props, interaction states use the _-prefixed style props (_pressed, _hover), and global customization lives in the theme. This mirrors utility-first styling but in a component/props form.
graph TD
A[Customize NativeBase Button] --> B[Per-instance props: variant, colorScheme, size]
A --> C[Style props: bg, borderRadius, px, _text]
A --> D[State props: _pressed, _hover, _disabled]
A --> E[App-wide: extendTheme → components.Button]
style E fill:#1e1b4b,color:#fff
Built-in Props
import { Button } from "native-base";
<Button variant="solid" colorScheme="primary">Solid</Button>
<Button variant="outline" colorScheme="secondary">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
<Button size="sm">Small</Button>
<Button size="lg">Large</Button>
variant-solid,outline,ghost,link,unstyled.colorScheme- a theme color key (primary,secondary,danger, or your custom palette).size-xs,sm,md,lg.
Inline Style Props
NativeBase exposes style props directly on the component:
<Button
bg="indigo.600" // background color
borderRadius="full" // pill shape
px={6} py={3} // horizontal/vertical padding
_text={{ fontSize: "md", fontWeight: "bold", color: "white" }} // label styling
>
Custom
</Button>
The _text prop styles the inner text; this nested-style pattern is how you reach child elements.
Styling Interaction States
The _-prefixed props target states:
<Button
bg="indigo.600"
_pressed={{ bg: "indigo.800" }} // while pressed
_hover={{ bg: "indigo.700" }} // on web hover
_disabled={{ opacity: 0.4 }} // when disabled
>
Stateful
</Button>
Icons and Loading State
import { Button, Icon } from "native-base";
import { MaterialIcons } from "@expo/vector-icons";
<Button leftIcon={<Icon as={MaterialIcons} name="save" size="sm" />}>
Save
</Button>
<Button isLoading isLoadingText="Submitting">Submit</Button>
isLoading automatically shows a spinner and disables the button - no manual state plumbing for the visual.
App-Wide Customization via Theme
For consistent buttons across the app, override the Button component in a custom theme with extendTheme:
import { extendTheme, NativeBaseProvider } from "native-base";
const theme = extendTheme({
components: {
Button: {
baseStyle: { borderRadius: "lg" },
defaultProps: { colorScheme: "indigo", size: "md" },
variants: {
brand: () => ({ bg: "indigo.600", _text: { color: "white" } }),
},
},
},
colors: {
indigo: { 600: "#6366f1", 700: "#4f46e5", 800: "#4338ca" },
},
});
// wrap the app:
<NativeBaseProvider theme={theme}>{/* ... */}</NativeBaseProvider>
// then anywhere:
<Button variant="brand">Branded</Button>
baseStyle applies to all buttons, defaultProps sets defaults, and custom variants create reusable named styles.
Why This Matters in Interviews
React Native / NativeBase questions check whether you customize via the theming system rather than scattering inline styles. The progression to demonstrate: per-instance props (variant, colorScheme, size) → style props (bg, _text) → state props (_pressed) → app-wide extendTheme overrides with custom variants. Knowing _text for the label and _pressed/_hover for states, plus built-in isLoading, shows real familiarity.
Common Pitfalls
- Trying to style the button label with top-level props instead of
_text. - Hard-coding styles inline everywhere instead of defining a theme variant for consistency.
- Forgetting to wrap the app in
NativeBaseProviderwith the custom theme (overrides won't apply). - Using raw React Native
StyleSheetand losing NativeBase's responsive/themed tokens.
References
- NativeBase Button: https://docs.nativebase.io/button
- NativeBase customizing components: https://docs.nativebase.io/customizing-components