Hello I'll preface this by saying that I am pretty new to React and coding in general. I am currently going through the React Doc and learning. So sorry if this is trivial.
I am having an issue code here : https://pastebin.com/rkwS1x66 where I am trying to update a table based on a user clicking a button. I'm confident that my logic is solid up until the actual render. My click handling function works fine and on toggle it can display the url change through an alert(). The problem is that although the URL variable changes, the table does not re-render. I want the table to essentially re-render and show the different API call. Basically, it should show either the SWAP api or Pokemon api rendered in the table dynamically based on the button click.
The link contains my condensed code. My project contains more code but I thought this would suffice for the issue at hand.
function HeaderSection() {
let baseUrl = "https://swapi.dev/api/people";
const [data, setData] = useState([]);
const [currentStatus , setStatus] = useState(false);
let urlToggle = false;
function urlChange(){
urlToggle = !urlToggle;
if(urlToggle)
{
baseUrl = "https://swapi.dev/api/people";
}
else
{
baseUrl = "https://pokeapi.co/api/v2/berry";
}
}
useEffect(()=>{
fetch(baseUrl)
.then((response) =>{
if(!response.ok)
{
return Promise.reject( new Error("Response Error!"));
}
else
{
return response.json();
}
})
.catch ( (err) =>{
console.log(err);
})
.then((json) => {
try{
setData(json.results);
setStatus(true);
}
catch
{
return Promise.reject(new Error(`State Error!: Data: ${data} , Connection:${currentStatus}`));
}
})
.catch((err) =>{
console.log(err);
})
},[baseUrl]);
return (
<div className='gio-main'>
<div className='gio-container-3'>
<h1>API Switch</h1>
<h4>Endpoint request using vanilla JS displayed in custom table</h4>
<p>You can switch between endpoints using this button!</p>
<button onClick={urlChange}>Change API</button>
{!currentStatus ? <h2>Loading... </h2> : <Table data={data}/>}
</div>
</div>
);
}
export default HeaderSection;
CodePudding user response:
The reason why your useEffect
hook isn't triggering on baseUrl
and changes the value of data
as you expect is that baseUrl
isn't a state.
The second argument, the list of the useEffect
expect states, and will cause the useEffect
to ttriger on state change, so using a "normal" variable will not cause the hook to trigger.
To fix it simply change baseUrl
to a useState
.
In your code:
// change #1
const [baseUrl, setBaseUrl] = useState("https://swapi.dev/api/people");
//change #2
function urlChange(){
urlToggle = !urlToggle;
if(urlToggle)
{
setBaseUrl("https://swapi.dev/api/people");
}
else
{
setBaseUrl("https://pokeapi.co/api/v2/berry");
}
}
And now when the baseUrl changes the useEffect
hook will retrigger.
useEffect docs - look at the "note" part