проблема с загрузкой кнопок (без пакетов)

#javascript #reactjs #react-native

#javascript #reactjs #react-native

Вопрос:

  1. У меня есть пользовательский компонент счетчика кнопок, который я создаю:

      const ButtonSpinner = ({ onPress, title }) => {
         const { state } = useContext(AuthContext);
         const loading = state.loading;
         return (
             <TouchableOpacity
                 style={{ height: 20, width: 300, marginTop: 15, backgroundColor: "red" }}
                 onPress={onPress}
                 title={title}
             >
                 {loading ? (
                     <ActivityIndicator size={"large"} color={"black"} />
                 ) : (
                     <Text>{title}</Text>
                 )}
             </TouchableOpacity>
         );
     };
      

    экспортировать ButtonSpinner по умолчанию;

  2. у меня есть индикатор состояния загрузки внутри контекста использования

      const { state } = useContext(AuthContext);(//which work perfectlly)
      
  3. так что нет, я вызываю buttonSpinner с асинхронной функцией следующим образом :

              <ButtonSpinner
             onPress={() =>
                 signHandler(localSign, {
                     loginPage,
                     name,
                     email,
                     password,
                 })
             }
             title={"TITLE"}
         />
      

проблема: у меня есть несколько вызовов buttonspinnercomponent, и когда я нажимаю на одну кнопку, загрузчик ссылается на все компоненты «buttonspinner». ИЗОБРАЖЕНИЕ для повторного примера:
перед загрузкой

при загрузке

ВОПРОС: как я могу вызвать, чтобы показать загрузчик только в кнопке, которую я нажал, а не во всех моих кнопках.

Ответ №1:

Проблема в том, что вы используете свойство загрузки AuthContext только для отображения индикатора загрузки. Таким образом, загрузка всех ваших кнопок зависит от одного свойства. Вам нужно обработать свойство загрузки внутри кнопки таким образом, чтобы оно отображалось только при нажатии кнопки:

 import React, { useContext, useEffect, useState } from 'react';

const ButtonSpinner = ({ onPress, title }) => {
     const [localLoading, setLocalLoading] = useState(false);
     const { state } = useContext(AuthContext);
     const loading = state.loading;
     
     useEffect(() => {
         if (!loading) setLocalLoading(false);
     }, [loading]);

     const onButtonPress = () => {
         setLocalLoading(true);
         onPress();
     }

     return (
         <TouchableOpacity
             style={{ height: 20, width: 300, marginTop: 15, backgroundColor: "red" }}
             onPress={onButtonPress}
             title={title}
         >
             {(loading amp;amp; localLoading) ? (
                 <ActivityIndicator size={"large"} color={"black"} />
             ) : (
                 <Text>{title}</Text>
             )}
         </TouchableOpacity>
     );
};
export default ButtonSpinner;
  

Редактировать:

Если вы хотите удалить AuthContext, а onPress не возвращает обещание, вы можете передать обратный onPress вызов функции и обновить localLoading состояние:

 import React, { useContext, useEffect, useState } from 'react';

const ButtonSpinner = ({ onPress, title }) => {
     const [localLoading, setLocalLoading] = useState(false);

     const onButtonPress = () => {
         setLocalLoading(true);
         onPress(() => setLocalLoading(false));
     }

     return (
         <TouchableOpacity
             style={{ height: 20, width: 300, marginTop: 15, backgroundColor: "red" }}
             onPress={onButtonPress}
             title={title}
         >
             {localLoading ? (
                 <ActivityIndicator size={"large"} color={"black"} />
             ) : (
                 <Text>{title}</Text>
             )}
         </TouchableOpacity>
     );
};
export default ButtonSpinner;
  

И ButtonSpinner:

 const handlePress = async (cb) => {
  await signHandler(localSign, {  
    loginPage,
    name,
    email,
    password,
  });
  cb amp;amp; cb();
}

<ButtonSpinner
  onPress={handlePress}
  title={"TITLE"}
/>
  

Это будет работать в предположении, что signHandler это обещание. Если это не обещание, используйте тот же метод и передайте cb обработчику подписи и вызовите его, когда он будет завершен.

Комментарии:

1. Спасибо! сработало отлично, есть способ сделать это без контекста? я пробовал так: const onButtonPress = () => { setLocalLoading(true); onPress().затем(setLocalLoading(false)); }; и таким образом const onButtonPress = () => { setLocalLoading(true); onPress() (setLocalLoading(false)); }; но он не ожидает асинхронной функции.. итак, загрузчик не отображается

2. Вероятно, это не сработало, потому onPress() что не возвращает обещание. Я включу некоторый код в свой ответ по этому поводу

3. большое вам спасибо! я остаюсь в вашем первом решении… кажется более читаемым! еще раз спасибо

4. Нет проблем 🙂 🙂