最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Hook for a POST call onClick - Stack Overflow

programmeradmin0浏览0评论

I have a button, onClick of that button I want to make a POST call with some data user has filled in an input field, stored in state, and then redirect the user to another page.

My current code looks like this, but I get an error:

React Hook "usePost" is called in function "onAccept" which is neither a React function ponent or a custom React Hook function

And the code doesn't work. I have created my own hook for POST calls.

What might a way to make the desired functionality work?

What I'm after is the ability to make a POST call and redirect.

Simplified example:

// my function
const onAccept = () => {
  const { data, loading, error } = usePost(
    "MY_URL",
    { DATA: MY_DATA }
  );
  if (data && !error) {
    navigate(`/`);
  }
};

// return
<button onClick={() => onAccept()}

I have a button, onClick of that button I want to make a POST call with some data user has filled in an input field, stored in state, and then redirect the user to another page.

My current code looks like this, but I get an error:

React Hook "usePost" is called in function "onAccept" which is neither a React function ponent or a custom React Hook function

And the code doesn't work. I have created my own hook for POST calls.

What might a way to make the desired functionality work?

What I'm after is the ability to make a POST call and redirect.

Simplified example:

// my function
const onAccept = () => {
  const { data, loading, error } = usePost(
    "MY_URL",
    { DATA: MY_DATA }
  );
  if (data && !error) {
    navigate(`/`);
  }
};

// return
<button onClick={() => onAccept()}
Share Improve this question edited Jan 26 at 19:12 VLAZ 29.1k9 gold badges63 silver badges84 bronze badges asked Nov 4, 2022 at 13:21 matmikmatmik 6801 gold badge6 silver badges15 bronze badges 4
  • 1 Did you read the error message? – morganney Commented Nov 4, 2022 at 13:26
  • The error is pretty clear. You can't use custom hooks within functions. They have to be used in (at the top level) a ponent or another custom hook. – Andy Commented Nov 4, 2022 at 13:27
  • Yes I read the error message, but I'm confused what the way to fix it would be? Do I get rid of the custom hook and paste the code from the hook to the onAccept function in order to make a post call? – matmik Commented Nov 4, 2022 at 13:29
  • Thanks @Andy - does that mean that a "dynamic" use of the usePost through the onClick is not possible to achieve? Seems like a custom hook for making POST calls is not a thing then, as often the call contains data from a form / page otherwise? – matmik Commented Nov 4, 2022 at 13:33
Add a ment  | 

3 Answers 3

Reset to default 4

I can suggest you do the following.

At first, you should create fetch function which will be returned from usePost hook.

example.

export const usePost = () => {
  const [loading, setLoading] = useState(false)
  const [data, setData] = useState([])

  const fetch = () => {
    setLoading(loading)
    apiRequest({
      url: 'my_url',
      method: 'GET',
   
    }).then(response => {
      setLoading(false)
      setData(response.data.data)
    }).catch(e => {
      setLoading(false)
    })
  }

  return {
    status,
    data,
    fetch
  }

After all, you can call this hook in your ponent. It will return fetch function. You should call fetch inside onAccept.

Example.

const { data, loading, fetch } = usePost()

const onAccept = () => {
    fetch()
 }

// return
<button onClick={() => onAccept()}

   

PS. if you need you can return errors from usePost hook, as well.

Yes, You are calling usePost hook inside of onAccept function. You should follow react hook rule.

To solve your problem, you can do like that:

your custom hook file:

export const usePost = () => {
  const [status, setStatus] = useState()

  const handlePost = useCallback(async (url, data) => {
    // your api request logic in here, bellow only show example
    try {
      const {data, status} = await apiCall(url, data)
      if (data && status === 200) navigate(`/`)
    } catch (error) {
      console.log(error)
    }
  }, [])

  return { handlePost }
  // to return status to ponent, you can use bellow.
  // return { status, handlePost }
}

then your ponent:

const YourComponent: React.FC = () => {
  const { handlePost } = usePost()
  // To get status: const { status, handlePost } = usePost()
  // your other hooks in here
  // Check status
  useEffect(() => {
    if (status === 200) {
      // whatever you want to do
    }
  }, [status])
  
  return (
    <>
      // Your ponent UI here
      ...
      <button onClick={() => handlePost(url, data)}>
    </>
  )
}

You should call your custom hooks(for example: usePost) at the top level of ponent, not nested function body as like as you were doing in your code (onAccept function body).

First, call you hook from React Function. Read the docs: https://reactjs/docs/hooks-rules.html#only-call-hooks-from-react-functions.

Second, you should have some sort of load method in your usePost hook, e.g.: const { load } = usePost(...), in order to make POST request on click.

So your handler will look like:

const onAccept = () => {
  load();

  // the following block move somewhere before you render the ponent or better use useEffect hook for that
  // if (data && !error) {
  //   navigate(`/`);
  // }
};

I hope this will help.

发布评论

评论列表(0)

  1. 暂无评论