I would declare both functions at the beginning of the component (you can later optimise them with useCallback but it's not that important in this phase).
const getTracks = async () => {
  await httpClient.get(`/track/${id}`)
    .then((response) => {
      setTrack(response.data);
    })
  }
const getUser = async() => {
  await httpClient.get(`/profile/${track.user}/`)
    .then((response) => {
      setUser(response.data);
  })
}
I would then call an async function inside the useEffect hook. There are a couple of ways of doing it: you can either declare an async function in the useEffect hook and call it immediately, or you can call an anonymous async function. I prefer the latter for brevity, so here it is:
useEffect(() => {
  (async () => {
    await getTracks();
    getUser();
  })();
}, []);
Now when you call getUser you should be sure that getTracks has already set the track variable.
Here is the complete component:
const Player = ({trackUrl, index, cover, id}) => {
  const [track, setTrack] = useState({})
  const [user, setUser] = useState({})
  const getTracks = async () => {
    await httpClient.get(`/track/${id}`)
      .then((response) => {
        setTrack(response.data);
      })
    }
  const getUser = async() => {
    await httpClient.get(`/profile/${track.user}/`)
      .then((response) => {
        setUser(response.data);
      })
    }
  useEffect(() => {
    (async () => {
      await getTracks();
      getUser();
    })();
  }, []);
}
EDIT 07/18/22
Following Noel's comments and linked sandbox, I figured out that my answer wasn't working. The reason why it wasn't working is that the track variable was't available right after the getTrack() hook execution: it would have been available on the subsequent render.
My solution is to add a second useEffect hook that's executed every time the track variable changes. I have created two solutions with jsonplaceholder endpoints, one (see here) which preserves the most of the original solution but adds complexity, and another one (here) which simplifies a lot the code by decoupling the two methods from the setTrack and setUser hooks.
I'll paste here the simpler one, adapted to the OP requests.
export default function Player({ trackUrl, index, cover, id }) {
  const [track, setTrack] = useState({});
  const [user, setUser] = useState({});
  const getTracks = async () => {
    // only return the value of the call
    return await httpClient.get(`/track/${id}`);
  };
  const getUser = async (track) => {
    // take track as a parameter and call the endpoint
    console.log(track, track.id, 'test');
    return await httpClient.get(`profile/${track.user}`);
  };
  useEffect(() => {
    (async () => {
      const trackResult = await getTracks();
      // we call setTrack outside of `getTracks`
      setTrack(trackResult);
    })();
  }, []);
  useEffect(() => {
    (async () => {
      if (track && Object.entries(track).length > 0) {
        // we only call `getUser` if we are sure that track has at least one entry
        const userResult = await getUser(track);
        console.log(userResult);
        setUser(userResult);
      }
    })();
  }, [track]);
  return (
    <div className="App">{user && user.id ? user.id : "Not computed"}</div>
  );
}
     
    
getUserfunction? Do you just want it to run on component mount? Or will it be some event handler's function, like when they click a button?