React Native Hooks 快速参考卡
🎯 项目自定义 Hooks
useRefreshTrigger
javascript
import { useRefreshTrigger } from '@/hooks';
const [trigger, fire] = useRefreshTrigger();
<Component refreshTrigger={trigger} />
<Button onPress={fire}>刷新</Button>
useToggle
javascript
import { useToggle } from '@/hooks';
const [isOpen, { toggle, setTrue, setFalse }] = useToggle(false);
<Modal visible={isOpen} onClose={setFalse} />
useDebounce
javascript
import { useDebounce } from '@/hooks';
const [text, setText] = useState('');
const debouncedText = useDebounce(text, 500);
useAsync
javascript
import { useAsync } from '@/hooks';
const { loading, data, error, execute } = useAsync(fetchData);
useEffect(() => { execute(id); }, [id]);
usePrevious
javascript
import { usePrevious } from '@/hooks';
const prevValue = usePrevious(currentValue);
📦 推荐第三方库
ahooks(推荐安装)
bash
yarn add ahooks
状态管理
javascript
import { useBoolean, useToggle, useSet, useMap } from 'ahooks';
const [state, { toggle, setTrue, setFalse }] = useBoolean(false);
副作用
javascript
import { useDebounce, useThrottle, useInterval } from 'ahooks';
const debouncedValue = useDebounce(value, { wait: 500 });
数据请求
javascript
import { useRequest } from 'ahooks';
const { data, loading, error, run, refresh } = useRequest(getUser, {
manual: true,
debounceWait: 300,
onSuccess: (data) => console.log(data),
});
生命周期
javascript
import { useMount, useUnmount, useUpdateEffect } from 'ahooks';
useMount(() => console.log('组件挂载'));
useUnmount(() => console.log('组件卸载'));
useUpdateEffect(() => console.log('更新,跳过首次'), [dep]);
@react-native-community/hooks
bash
yarn add @react-native-community/hooks
javascript
import {
useAppState, // 应用前后台状态
useBackHandler, // Android 返回键
useClipboard, // 剪贴板
useDimensions, // 屏幕尺寸
useKeyboard, // 键盘状态
useDeviceOrientation, // 设备方向
useLayout, // 组件布局
} from '@react-native-community/hooks';
// 应用状态
const appState = useAppState(); // 'active' | 'background' | 'inactive'
// 返回键
useBackHandler(() => {
// 返回 true 阻止默认行为
return true;
});
// 剪贴板
const [data, setString] = useClipboard();
// 屏幕尺寸
const { screen, window } = useDimensions();
// 键盘
const keyboard = useKeyboard();
// keyboard.keyboardShown: boolean
// keyboard.keyboardHeight: number
// 设备方向
const orientation = useDeviceOrientation(); // 'portrait' | 'landscape'
// 布局
const { onLayout, width, height, x, y } = useLayout();
<View onLayout={onLayout} />
react-hook-form
bash
yarn add react-hook-form
javascript
import { useForm, Controller } from 'react-hook-form';
const { control, handleSubmit, formState: { errors } } = useForm();
<Controller
control={control}
name="email"
rules={{ required: '必填' }}
render={({ field: { onChange, value } }) => (
<TextInput value={value} onChangeText={onChange} />
)}
/>
@tanstack/react-query
bash
yarn add @tanstack/react-query
javascript
import { useQuery, useMutation } from '@tanstack/react-query';
// 查询
const { data, isLoading, error, refetch } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
staleTime: 5000,
});
// 修改
const mutation = useMutation({
mutationFn: createUser,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['users'] });
},
});
zustand
bash
yarn add zustand
javascript
import { create } from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
// 使用
const count = useStore((state) => state.count);
const increment = useStore((state) => state.increment);
@react-navigation/native
javascript
import {
useNavigation,
useRoute,
useFocusEffect,
useIsFocused,
} from '@react-navigation/native';
const navigation = useNavigation();
const route = useRoute();
const isFocused = useIsFocused();
useFocusEffect(
useCallback(() => {
// 页面聚焦时执行
return () => {
// 页面失焦时执行
};
}, [])
);
🔥 常见场景速查
搜索防抖
javascript
const [keyword, setKeyword] = useState('');
const debouncedKeyword = useDebounce(keyword, 500);
useEffect(() => {
if (debouncedKeyword) {
searchAPI(debouncedKeyword);
}
}, [debouncedKeyword]);
模态框控制
javascript
const [visible, { setTrue: open, setFalse: close }] = useToggle(false);
<Modal visible={visible} onClose={close}>
<Button onPress={close}>关闭</Button>
</Modal>
列表刷新
javascript
const [refreshTrigger, triggerRefresh] = useRefreshTrigger();
const refresh = () => {
fetchData();
triggerRefresh();
};
<FlatList
data={data}
renderItem={({ item }) => (
<ItemCard refreshTrigger={refreshTrigger} />
)}
/>
键盘适配
javascript
const keyboard = useKeyboard();
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
keyboardVerticalOffset={keyboard.keyboardHeight}>
<TextInput />
</KeyboardAvoidingView>
页面聚焦刷新
javascript
useFocusEffect(
useCallback(() => {
fetchData();
}, [])
);
返回键拦截
javascript
useBackHandler(() => {
if (hasUnsavedChanges) {
Alert.alert('提示', '有未保存的更改');
return true; // 阻止返回
}
return false; // 允许返回
});
异步数据加载
javascript
const { loading, data, error, execute } = useAsync(fetchUser);
useEffect(() => {
execute(userId);
}, [userId]);
if (loading) return <Loading />;
if (error) return <Error message={error.message} />;
return <UserProfile data={data} />;
表单验证
javascript
const { control, handleSubmit, formState: { errors } } = useForm();
const onSubmit = (data) => {
console.log(data);
};
<Controller
control={control}
name="email"
rules={{
required: '邮箱必填',
pattern: {
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
message: '邮箱格式不正确'
}
}}
render={({ field: { onChange, value } }) => (
<TextInput value={value} onChangeText={onChange} />
)}
/>
{errors.email && <Text>{errors.email.message}</Text>}
<Button onPress={handleSubmit(onSubmit)}>提交</Button>
📖 完整文档
提示: 将此文件保存为书签,随时查阅!