Let's fetch data from jsonplaceholder and set a state with useState() hook upon success or error, which will lead to a render. We put artificial 1s delay function between request and response to be able to see a state change on a screen, otherwise it happens too fast.
function sleeper(ms) {
return function(x) {
return new Promise(resolve => setTimeout(() => resolve(x), ms));
};
}
Jsonplaceholder returns 100 items, so every time we ask data under number 101 and more we get an error for our http request.
import axios from 'axios'
import randomNumFromTo from '/functions/randomNumFromTo';
import sleeper from '/functions/sleeper';
function ComponentWithUseState() {
const [state, setState] = useState({ loading: false, errorMsg: '', title: '', postNum: -1 })
function getTitle() {
const postNum = randomNumFromTo(1, 150)
const url = `https://jsonplaceholder.typicode.com/posts/${postNum}`
setState({ ...state, loading: true, postNum: postNum, errorMsg: '' })
axios(url)
.then(sleeper(1000))
.then(res => setState({ loading: false, errorMsg: '', title: res.data.title, postNum: postNum }))
.catch(() => setState({ loading: false, errorMsg: 'ERROR', title: '', postNum: postNum }))
}
return (
<>
<button onClick={getTitle}>Get post titles</button> 
Post #{state.postNum}   Title: {state.loading ? 'Loading...' : state.title}  
<span style={{ color: 'red' }}>{state.errorMsg}</span>
</>
)
}