Неверный вызов ловушки React - PullRequest
1 голос
/ 01 августа 2020

https://reactjs.org/docs/hooks-custom.html Создание собственных хуков позволяет вам извлекать logi компонентов c в функции многократного использования. Это то, что я хочу сделать: извлечь мои logi компонентов c в повторно используемые функции для других компонентов.

Мой функциональный компонент:

//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);
}

Как мне использовать свою функцию в опоре onRefre sh в моем списке пользователей? Я получаю сообщение об ошибке: Неверный вызов ловушки введите описание изображения здесь

Ответы [ 2 ]

2 голосов
/ 01 августа 2020

Вы используете 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} />;
}
0 голосов
/ 01 августа 2020

Перехватчики React не могут быть асинхронной c функцией. Итак, согласно этому рабочему процессу редукции: enter image description here

You have to dispatch fetch user's action and then your loading and error states should be in your reducer and if you have any side effect manager such as redux-saga alongside your redux, you have to call all HTTP methods right there and your components just should dispatch and present the results. The other way is to call and fetch users into your hook and put them into your redux store via an action which you dispatch. In this way, loading and error can be in your hook(in your local hook state, not into the redux-store).

So let's try this code(I've implemented the second way):

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);
          }
      })()
    }, [])
}
...