https://reactjs.org/docs/hooks-custom.html 通过构建自己的Hook,可以将组件逻辑提取到可重用的函数中。 那就是我想要做的:将我的组件逻辑提取到其他组件的可重用函数中。
我的功能组件:
//React
import React from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';
//Local
import UserPreview from './UserPreview';
import defaultContainer from '../../shared/styles/defaultContainer';
import useFetchUsers from './../../../handler/useFetchUsers';
export default function UserList(props) {
const { users } = props;
const dispatch = useDispatch();
//State
const [isLoading, setIsLoading] = React.useState(false);
const [error, setError] = React.useState(null);
return (
<View style={defaultContainer}>
<FlatList
data={users}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <UserPreview user={item} />}
ListEmptyComponent={() => <Text style={styles.listEmpty}>Keine Benutzer gefunden!</Text>}
ItemSeparatorComponent={() => <View style={styles.listSeperator} />}
onRefresh={useFetchUsers}
refreshing={isLoading}
contentContainerStyle={styles.container}
/>
</View>
);
}
我的可重用功能:
import React from 'react';
import * as userActions from '../store/actions/user';
import { useDispatch } from 'react-redux';
export default async function useFetchUsers() {
const [error, setError] = React.useState(null);
const dispatch = useDispatch();
const [isLoading, setIsLoading] = React.useState(false);
console.log('StartupScreen: User laden');
setIsLoading(true);
setError(null);
try {
await dispatch(userActions.fetchUsers());
console.log('StartupScreen: User erfolgreich geladen');
} catch (err) {
setError(err.message);
}
setIsLoading(false);
}
答案 0 :(得分:2)
您正在使用useFetchUsers
作为回调。钩子规则禁止这样做。
useFetchUsers
应该返回一些可用作回调的函数:
export default function useFetchUsers() {
const [error, setError] = React.useState(null);
const dispatch = useDispatch();
const [isLoading, setIsLoading] = React.useState(false);
return async function() {
console.log('StartupScreen: User laden');
setIsLoading(true);
setError(null);
try {
await dispatch(userActions.fetchUsers());
console.log('StartupScreen: User erfolgreich geladen');
} catch (err) {
setError(err.message);
}
setIsLoading(false);
}
}
function UserList(props) {
...
const handleRefresh = useFetchUsers();
...
return <FlatList onRefresh={handleRefresh} />;
}
答案 1 :(得分:0)
您必须分派获取用户的操作,然后您的加载和错误状态应该在您的reducer中,如果您在redux旁边有任何副作用管理器(例如redux-saga),则必须在那里调用所有HTTP方法,并且组件只应调度并显示结果。另一种方法是将用户调用并提取到您的钩子中,然后通过您调度的操作将其放入您的redux存储中。 这样,加载和错误可能就在您的钩子上(在本地钩子状态,而不是在redux存储中)。
所以让我们尝试下面的代码(我已经实现了第二种方式):
import React from 'react';
import * as userActions from '../store/actions/user';
import { useDispatch } from 'react-redux';
export default function useFetchUsers() {
const [error, setError] = React.useState(null);
const dispatch = useDispatch();
const [isLoading, setIsLoading] = React.useState(false);
React.useEffect(() => {
(async () => {
console.log('StartupScreen: User laden');
setIsLoading(true);
setError(null);
try {
const res = await fetchUsers();
dispatch(setUsers(res.data));
console.log('StartupScreen: User erfolgreich geladen');
setIsLoading(false);
} catch (err) {
setIsLoading(false);
setError(err.message);
}
})()
}, [])
}