import { memo, useCallback, useMemo, useReducer } from 'react';
import { FlatList, StyleSheet, TextInput, View } from 'react-native';
import { Row } from './Row';
import { useDebounced } from './useDebounced';
type Item = { id: string; title: string };
type State = { query: string; selected: Set<string> };
type Action =
| { type: 'query'; query: string }
| { type: 'toggle'; id: string };
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'query':
return { ...state, query: action.query };
case 'toggle': {
const selected = new Set(state.selected);
selected.has(action.id) ? selected.delete(action.id) : selected.add(action.id);
return { ...state, selected };
}
}
}
const MemoRow = memo(Row);
export function SearchScreen({ items }: { items: Item[] }) {
const [state, dispatch] = useReducer(reducer, { query: '', selected: new Set<string>() });
const query = useDebounced(state.query.trim().toLowerCase());
const visible = useMemo(
() => (query ? items.filter((item) => item.title.toLowerCase().includes(query)) : items),
[items, query],
);
const renderItem = useCallback(
({ item }: { item: Item }) => (
<MemoRow title={item.title} onPress={() => dispatch({ type: 'toggle', id: item.id })} />
),
[],
);
return (
<View style={styles.screen}>
<TextInput
placeholder="Search"
value={state.query}
onChangeText={(text) => dispatch({ type: 'query', query: text })}
style={styles.search}
/>
<FlatList data={visible} keyExtractor={(item) => item.id} renderItem={renderItem} initialNumToRender={20} />
</View>
);
}
const styles = StyleSheet.create({
screen: { flex: 1, padding: 16 },
search: { borderWidth: 1, borderColor: '#d0d7de', borderRadius: 6, padding: 12, marginBottom: 12 },
});