【问题标题】:button loading problem (without packages )按钮加载问题(没有包)
【发布时间】:2020-11-04 11:44:41
【问题描述】:
  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”组件。 例如图片: before loading

when loading

问题:如何调用以仅在我单击的按钮中显示加载程序,而不是在我的所有 buttonSpinner 中显示加载程序

【问题讨论】:

    标签: javascript reactjs react-native


    【解决方案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 && localLoading) ? (
                     <ActivityIndicator size={"large"} color={"black"} />
                 ) : (
                     <Text>{title}</Text>
                 )}
             </TouchableOpacity>
         );
    };
    export default ButtonSpinner;
    

    编辑:

    如果要移除 AuthContext 并且 onPress 不返回 Promise,可以将回调传递给 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 && cb();
    }
    
    <ButtonSpinner
      onPress={handlePress}
      title={"TITLE"}
    />
    

    这将在 signHandler 是一个 Promise 的假设下工作。如果不是 Promise,请使用相同的技术并将 cb 传递给 signHandler 并在完成时调用它。

    【讨论】:

    • 谢谢!工作得很好,有没有办法在没有上下文的情况下做到这一点?我试过这样: const onButtonPress = () => { setLocalLoading(true); onPress().then(setLocalLoading(false)); };这样 const onButtonPress = () => { setLocalLoading(true); onPress() (setLocalLoading(false)); };但它没有等待异步功能..所以加载器没有显示
    • 这可能不起作用,因为onPress() 没有返回承诺。我将在我的回答中包含一些代码
    • 非常感谢!我留在你的第一个解决方案中......似乎更具可读性!再次感谢
    • 没问题:) :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    • 2016-06-12
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多