【问题标题】:react button is called before onPress when using Hooks使用 Hooks 时在 onPress 之前调用反应按钮
【发布时间】:2020-02-20 02:31:24
【问题描述】:

我正在尝试使用钩子请求API request。但我的问题是我的函数在我onPress 之前被调用。

我有一个这样的自定义 API 组件:

const FetchDataPut = (URL) => {

  useEffect(() => {
      async function fetchData() {
          const res = await axios({
                    method: 'put',
                    url: URL,
                    data:{
                      name:'111',
                      email:'222',
                      password:'333',
                      id:'444',
                      phone:'555'
                    }
                  });
          const response = await res;
          console.log(response, 'completed')
      }
      fetchData()
  },[])
  return null
}

我可以从console.log 看到,api 请求有completed。我的问题是我的api component 在我按下按钮之前被调用。

这是我的 Button 组件:

const EditAccount = (props) => {

  const Desktop = () => {
    const URL = `MyURL...`
    return (
      <View>
        <Button title='edit account' onPress={FetchDataPut(URL)}/>
      </View>
    )
  }

  return(
    <div>
      <Desktop/>
    </div>
  )
}

如果我将 onPress 函数更改为如下箭头函数: onPress={()=&gt;FetchDataPut(URL)} 组件在我 onPress 之前没有被调用。但它会给我一个错误Invalid hook call. Hooks can only be called inside of the body of a function component

当我 onPress Button 时,知道如何处理我的 api 请求吗?

任何 cmets 或建议都会非常有帮助。提前致谢! :)

【问题讨论】:

    标签: reactjs react-native react-hooks


    【解决方案1】:

    我认为要走的路是使用钩子而不是组件:

    const useFetchDataPut = () => {
        const [url, setUrl] = useState("");
    
        useEffect(() => {
            if (!url) return;
    
            async function fetchData() {
                const res = await axios({
                    method: "put",
                    url,
                    data: {
                        name: "111",
                        email: "222",
                        password: "333",
                        id: "444",
                        phone: "555"
                    }
                });
                const response = await res;
                console.log(response, "completed");
            }
            fetchData();
        }, [url]);
    
        return setUrl;
    };
    

    然后在你按下按钮时调用它。 Desktop 也应该在 EditAccount 组件之外定义。

    const Desktop = () => {
        const setUrl = useFetchDataPut();
    
        return (
            <View>
                <Button
                    title="edit account"
                    onPress={() => setUrl("https://...")}
                />
            </View>
        );
    };
    
    const EditAccount = props => {
        return (
            <div>
                <Desktop />
            </div>
        );
    };
    

    如果有什么不清楚的地方请告诉我。

    【讨论】:

    • 非常感谢您的回答,请尝试一下并告诉您:)
    • 不客气,如果您需要进一步解释,请告诉我
    【解决方案2】:

    这里有几个问题。

    您将 onPress 属性设置为 调用 FetchDataPut(URL) 的结果。 prop 应该是函数本身,而不是调用它的结果。通过使用箭头函数,您声明了一个新函数,该函数在调用时会调用 FetchDataPut。

    如果您在按下按钮时调用它,则不需要它是一个钩子。

    另外,FetchDataPut 不是 React 组件。

    自行声明数据获取函数:

    async function fetchData(url) {
      return axios({
        method: 'put',
        url: URL,
        data: {
           name:'111',
           email:'222',
           password:'333',
           id:'444',
           phone:'555'
         }
      })
    }
    

    然后在按下按钮时调用它。

    const handler = async function ( ) {
      // or just inline the axios request right here
      // instead of declaring a separate function for it. 
      const result = await fetchData(url);
    
      // do something with the result
    }
    
    <Button onPress={handler} />
    

    对频繁的修改表示歉意。试图通过我的手机做到这一点。

    【讨论】:

    • 感谢您的回答,您的解决方案运行良好。我希望我能接受 2 个答案,但 @Alvaro 的答案更适合我的情况。总之真的很感激!
    猜你喜欢
    • 1970-01-01
    • 2021-08-04
    • 2016-12-31
    • 2020-07-26
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    • 1970-01-01
    相关资源
    最近更新 更多