React Native component used to select a single value from a range of values.
—
Reference-based methods for programmatic value updates and control, allowing external manipulation of slider values without user interaction.
Interface for programmatically controlling slider values through React refs.
interface SliderRef {
/**
* Programmatically update the slider value
* @param value - New value to set (must be within min/max range)
*/
updateValue(value: number): void;
}
type SliderReferenceType =
| (React.MutableRefObject<SliderRef> & React.LegacyRef<Slider>)
| undefined;
interface SliderRefProps {
/**
* Reference object for programmatic control
*/
ref?: SliderReferenceType;
}Usage Examples:
import React, { useRef, useState } from 'react';
import { View, Text, Button } from 'react-native';
import Slider from '@react-native-community/slider';
import type { SliderRef } from '@react-native-community/slider';
// Basic programmatic control
function ProgrammaticSlider() {
const sliderRef = useRef<SliderRef>(null);
const [currentValue, setCurrentValue] = useState(50);
const setToMinimum = () => {
sliderRef.current?.updateValue(0);
};
const setToMaximum = () => {
sliderRef.current?.updateValue(100);
};
const setToMiddle = () => {
sliderRef.current?.updateValue(50);
};
return (
<View>
<Text>Current Value: {currentValue}</Text>
<Slider
ref={sliderRef}
style={{width: 300, height: 40}}
minimumValue={0}
maximumValue={100}
value={currentValue}
onValueChange={setCurrentValue}
/>
<View style={{flexDirection: 'row', gap: 10}}>
<Button title="Min (0)" onPress={setToMinimum} />
<Button title="Mid (50)" onPress={setToMiddle} />
<Button title="Max (100)" onPress={setToMaximum} />
</View>
</View>
);
}
// Animated value updates
function AnimatedSlider() {
const sliderRef = useRef<SliderRef>(null);
const [currentValue, setCurrentValue] = useState(0);
const [isAnimating, setIsAnimating] = useState(false);
const animateToValue = (targetValue: number) => {
if (isAnimating) return;
setIsAnimating(true);
const startValue = currentValue;
const difference = targetValue - startValue;
const duration = 1000; // 1 second
const steps = 60; // 60 FPS
const stepValue = difference / steps;
let currentStep = 0;
const interval = setInterval(() => {
currentStep++;
const newValue = startValue + (stepValue * currentStep);
sliderRef.current?.updateValue(newValue);
if (currentStep >= steps) {
clearInterval(interval);
setIsAnimating(false);
sliderRef.current?.updateValue(targetValue); // Ensure exact final value
}
}, duration / steps);
};
return (
<View>
<Text>Animated Value: {currentValue.toFixed(1)}</Text>
<Slider
ref={sliderRef}
style={{width: 300, height: 40}}
minimumValue={0}
maximumValue={100}
value={currentValue}
onValueChange={setCurrentValue}
disabled={isAnimating}
/>
<View style={{flexDirection: 'row', gap: 10}}>
<Button
title="Animate to 25"
onPress={() => animateToValue(25)}
disabled={isAnimating}
/>
<Button
title="Animate to 75"
onPress={() => animateToValue(75)}
disabled={isAnimating}
/>
</View>
</View>
);
}Common patterns for controlling sliders from external sources like APIs, timers, or other components.
Usage Examples:
import React, { useRef, useState, useEffect } from 'react';
import { View, Text, Button } from 'react-native';
import Slider from '@react-native-community/slider';
// Timer-controlled slider
function TimerControlledSlider() {
const sliderRef = useRef<SliderRef>(null);
const [progress, setProgress] = useState(0);
const [isRunning, setIsRunning] = useState(false);
useEffect(() => {
if (!isRunning) return;
const interval = setInterval(() => {
setProgress(prev => {
const newValue = prev + 1;
if (newValue >= 100) {
setIsRunning(false);
return 100;
}
sliderRef.current?.updateValue(newValue);
return newValue;
});
}, 100); // Update every 100ms
return () => clearInterval(interval);
}, [isRunning]);
const startTimer = () => {
setIsRunning(true);
};
const stopTimer = () => {
setIsRunning(false);
};
const resetTimer = () => {
setIsRunning(false);
setProgress(0);
sliderRef.current?.updateValue(0);
};
return (
<View>
<Text>Progress: {progress}%</Text>
<Slider
ref={sliderRef}
style={{width: 300, height: 40}}
minimumValue={0}
maximumValue={100}
value={progress}
onValueChange={setProgress}
disabled={isRunning}
/>
<View style={{flexDirection: 'row', gap: 10}}>
<Button title="Start" onPress={startTimer} disabled={isRunning} />
<Button title="Stop" onPress={stopTimer} disabled={!isRunning} />
<Button title="Reset" onPress={resetTimer} />
</View>
</View>
);
}
// Network-controlled slider
function NetworkControlledSlider() {
const sliderRef = useRef<SliderRef>(null);
const [volume, setVolume] = useState(50);
const [isLoading, setIsLoading] = useState(false);
// Simulate API call to update volume
const syncWithServer = async (newVolume: number) => {
setIsLoading(true);
try {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 500));
// Update slider with server response
sliderRef.current?.updateValue(newVolume);
setVolume(newVolume);
} catch (error) {
console.error('Failed to sync with server:', error);
} finally {
setIsLoading(false);
}
};
// Simulate receiving updates from server
const simulateServerUpdate = () => {
const randomVolume = Math.floor(Math.random() * 100);
syncWithServer(randomVolume);
};
return (
<View>
<Text>Volume: {volume}% {isLoading && '(Syncing...)'}</Text>
<Slider
ref={sliderRef}
style={{width: 300, height: 40}}
minimumValue={0}
maximumValue={100}
value={volume}
onValueChange={(value) => {
setVolume(value);
// Could trigger debounced API call here
}}
disabled={isLoading}
/>
<Button
title="Simulate Server Update"
onPress={simulateServerUpdate}
disabled={isLoading}
/>
</View>
);
}Coordinating multiple sliders programmatically for complex UI scenarios.
Usage Examples:
import React, { useRef, useState } from 'react';
import { View, Text, Button } from 'react-native';
import Slider from '@react-native-community/slider';
// RGB Color picker with coordinated sliders
function RGBColorPicker() {
const redSliderRef = useRef<SliderRef>(null);
const greenSliderRef = useRef<SliderRef>(null);
const blueSliderRef = useRef<SliderRef>(null);
const [red, setRed] = useState(128);
const [green, setGreen] = useState(128);
const [blue, setBlue] = useState(128);
const setPresetColor = (r: number, g: number, b: number) => {
redSliderRef.current?.updateValue(r);
greenSliderRef.current?.updateValue(g);
blueSliderRef.current?.updateValue(b);
setRed(r);
setGreen(g);
setBlue(b);
};
const rgbColor = `rgb(${red}, ${green}, ${blue})`;
return (
<View>
<View style={{
width: 100,
height: 100,
backgroundColor: rgbColor,
marginBottom: 20,
borderRadius: 8,
}} />
<Text>RGB: ({red}, {green}, {blue})</Text>
<View style={{marginVertical: 10}}>
<Text>Red: {red}</Text>
<Slider
ref={redSliderRef}
style={{width: 300, height: 40}}
minimumValue={0}
maximumValue={255}
step={1}
value={red}
onValueChange={setRed}
minimumTrackTintColor="#ff0000"
/>
</View>
<View style={{marginVertical: 10}}>
<Text>Green: {green}</Text>
<Slider
ref={greenSliderRef}
style={{width: 300, height: 40}}
minimumValue={0}
maximumValue={255}
step={1}
value={green}
onValueChange={setGreen}
minimumTrackTintColor="#00ff00"
/>
</View>
<View style={{marginVertical: 10}}>
<Text>Blue: {blue}</Text>
<Slider
ref={blueSliderRef}
style={{width: 300, height: 40}}
minimumValue={0}
maximumValue={255}
step={1}
value={blue}
onValueChange={setBlue}
minimumTrackTintColor="#0000ff"
/>
</View>
<View style={{flexDirection: 'row', gap: 10, marginTop: 20}}>
<Button title="Red" onPress={() => setPresetColor(255, 0, 0)} />
<Button title="Green" onPress={() => setPresetColor(0, 255, 0)} />
<Button title="Blue" onPress={() => setPresetColor(0, 0, 255)} />
<Button title="Black" onPress={() => setPresetColor(0, 0, 0)} />
<Button title="White" onPress={() => setPresetColor(255, 255, 255)} />
</View>
</View>
);
}
// Master-slave slider relationship
function MasterSlaveSliders() {
const masterRef = useRef<SliderRef>(null);
const slave1Ref = useRef<SliderRef>(null);
const slave2Ref = useRef<SliderRef>(null);
const [masterValue, setMasterValue] = useState(50);
const [slave1Value, setSlave1Value] = useState(25);
const [slave2Value, setSlave2Value] = useState(75);
// When master changes, update slaves proportionally
const handleMasterChange = (value: number) => {
setMasterValue(value);
// Update slaves to maintain proportion
const slave1Proportion = value * 0.5; // 50% of master
const slave2Proportion = Math.min(100, value * 1.5); // 150% of master (clamped)
slave1Ref.current?.updateValue(slave1Proportion);
slave2Ref.current?.updateValue(slave2Proportion);
setSlave1Value(slave1Proportion);
setSlave2Value(slave2Proportion);
};
return (
<View>
<Text>Master Control System</Text>
<View style={{marginVertical: 10}}>
<Text>Master: {masterValue.toFixed(1)}</Text>
<Slider
ref={masterRef}
style={{width: 300, height: 40}}
minimumValue={0}
maximumValue={100}
value={masterValue}
onValueChange={handleMasterChange}
minimumTrackTintColor="#ff6b6b"
/>
</View>
<View style={{marginVertical: 10}}>
<Text>Slave 1 (50% of Master): {slave1Value.toFixed(1)}</Text>
<Slider
ref={slave1Ref}
style={{width: 300, height: 40}}
minimumValue={0}
maximumValue={100}
value={slave1Value}
onValueChange={setSlave1Value}
disabled={true} // Controlled by master
minimumTrackTintColor="#4ecdc4"
/>
</View>
<View style={{marginVertical: 10}}>
<Text>Slave 2 (150% of Master): {slave2Value.toFixed(1)}</Text>
<Slider
ref={slave2Ref}
style={{width: 300, height: 40}}
minimumValue={0}
maximumValue={100}
value={slave2Value}
onValueChange={setSlave2Value}
disabled={true} // Controlled by master
minimumTrackTintColor="#45b7d1"
/>
</View>
</View>
);
}Proper error handling when using programmatic control.
Usage Examples:
import React, { useRef, useState } from 'react';
import { View, Text, Button, Alert } from 'react-native';
import Slider from '@react-native-community/slider';
function ValidatedSlider() {
const sliderRef = useRef<SliderRef>(null);
const [value, setValue] = useState(50);
const [inputValue, setInputValue] = useState('50');
const updateSliderSafely = (newValue: number) => {
try {
// Validate the value is within bounds
const minValue = 0;
const maxValue = 100;
if (isNaN(newValue)) {
throw new Error('Value must be a number');
}
if (newValue < minValue || newValue > maxValue) {
throw new Error(`Value must be between ${minValue} and ${maxValue}`);
}
// Update the slider
sliderRef.current?.updateValue(newValue);
setValue(newValue);
setInputValue(newValue.toString());
} catch (error) {
Alert.alert('Invalid Value', error.message);
// Revert input to current valid value
setInputValue(value.toString());
}
};
const handleTextInput = (text: string) => {
setInputValue(text);
const numericValue = parseFloat(text);
if (!isNaN(numericValue)) {
updateSliderSafely(numericValue);
}
};
return (
<View>
<Text>Current Value: {value}</Text>
<Slider
ref={sliderRef}
style={{width: 300, height: 40}}
minimumValue={0}
maximumValue={100}
value={value}
onValueChange={setValue}
/>
<TextInput
style={{
borderWidth: 1,
borderColor: '#ccc',
padding: 8,
marginVertical: 10,
width: 100,
}}
value={inputValue}
onChangeText={handleTextInput}
keyboardType="numeric"
placeholder="Enter value"
/>
<View style={{flexDirection: 'row', gap: 10}}>
<Button title="Set to 25" onPress={() => updateSliderSafely(25)} />
<Button title="Set to 75" onPress={() => updateSliderSafely(75)} />
<Button title="Invalid (-10)" onPress={() => updateSliderSafely(-10)} />
</View>
</View>
);
}import type { React } from 'react';
interface SliderRef {
updateValue(value: number): void;
}
type SliderReferenceType =
| (React.MutableRefObject<SliderRef> & React.LegacyRef<Slider>)
| undefined;
interface SliderRefProps {
ref?: SliderReferenceType;
}// For use with useRef hook
type SliderRefHook = React.MutableRefObject<SliderRef | null>;
// For use with forwardRef pattern
type ForwardedSliderRef = React.ForwardedRef<SliderRef>;Install with Tessl CLI
npx tessl i tessl/npm-react-native-community--slider