How will I able to save in hooks that data from database. Since I need to display the data that I get to dropdown.
Here's my code
const [dataSystem, setdataSystem] = useState([])
const getAllSystems = async() => {
......
}
const getDependentSystems = async() => {
const response = await axios.get('/API' + ID)
console.log('LIST OF SYSTEM', response.data)
setdataSystem(response.data)
}
Since upon setState, data is not yet saved to dataSystem I need to trigger getDeoendetSystems() twice to display the list on my dropdown.
Result of console.log
LIST OF SYSTEM [{...},{...}]
0: {ID: 1, SYSTEMID: 12 ...},
1: {ID: 2, SYSTEMID: 13 ...}
Thank you
You need to load the data inside an useEffect like
function Component() {
const [dataSystem, setdataSystem] = useState([])
useEffect(() => {
getDependentSystems()
}, [])
const getDependentSystems = async() => {
const response = await axios.get('/API' + ID)
console.log('LIST OF SYSTEM', response.data)
setdataSystem(response.data)
}
return ...
}
Basically you want to call the function in the useEffect so you only call it once; cause if you call it in the component context, everytime the state updates it will call the api again which will trigger an infinite loop.
Related
Here simply I am fetching data from mysql DB and storing it in state and in order to fetch this data:
const [orders, setOrders] = useState([]);
To fetch data I am using different functions and finally I am calling those functions using useEffect simple enough and so for everything is working perfectly but the problem comes whenever I use the state as dependency where I am storing data beacause if I dont do that then I have to manually refresh the page for latest changes and I have tried every given solution on stackoverflow but any of the solution didnt work so someone can please help me how can I use this state as dependencey without causing infinite loop:
const [orders, setOrders] = useState([]);
const loadData = async () => {
const response = await fetch("http://localhost/k-shop/load.php");
const result = await response.json();
setOrders(result);
};
const loadTotal = async () => {
const response = await fetch("http://localhost/k-shop/amount.php");
const result = await response.json();
setTotal(result);
};
useEffect(() => {
loadData();
loadTotal();
}, [orders]);
console.log(orders);
If you move the state into the useEffect dependency, you can then check if it is empty, and only set it when that check passes.
It will set the state once to populate and not pass the check again.
const [orders, setOrders] = useState([]);
const loadData = async () => {
const response = await fetch("http://localhost/k-shop/load.php");
const result = await response.json();
setOrders(result);
};
const loadTotal = async () => {
const response = await fetch("http://localhost/k-shop/amount.php");
const result = await response.json();
setTotal(result);
};
useEffect(() => {
if(orders.length === 0) {
loadData();
}
// you can do the same with checking loadTotal() state
}, [orders]);
console.log(orders);
Avoid ,non-primitive data types in dependencyArray ,
useEffect(() => {
loadTotal();
loadData();
}, [total, orders.length]);
every times you "setOrders" means you change the state,every times you change the state,means the "useEffect" will do again.that cause infinite loops.why not try useEffect(() => {loadData()}, [])?
react won't work when rendering the page, but when i changed code in the vscode (added a line of console or comment one line out), the page is rendered. or when page is not rendered. when i hit refresh. i can see some of my content but it won't render. the usestate doesnt seem like to successfully save the value
const ParkDetail = () => {
const [parkId, setParkId] = useState('')
const [park, setpark] = useState('')
const [areas, setAreas] = useState([])
const [ridesName, setridesName] = useState([])
const [rides, setrides] = useState([])
let { id } = useParams()
console.log(id)
useEffect(() => {
async function getPark() {
try {
await setParkId(id)
const res = await axios.get(`/parks/details/${parkId}`)
console.log(res)
const park1 = await res.data.park
console.log(park1)
await setpark(park1)
console.log(park)
await setAreas(park1.serviceAnimalRelief)
// await setridesName(park1.topRides)
// console.log(ridesName)
} catch (e) {
console.log(e.message)
}
}
getPark()
}, [parkId])
}
I believe the problem is you using the state as parameters in your get requests. Since state setter functions do not return promises, using await on them is basically of no use. You should rather use the variables that you obtain from the get requests directly. For example, use id instead of parkId and so on.
when I fetch data from my api successfully, I can display it using console.log, but somehow after I use a setState, the state still keeps the previous data. so when the page loads, the console.log(data) has an array of object containing data from the api, but console.log(rute) after the setRute still returns empty array. why is that?
this is my code
const MasterRute = () => {
const [rute, setRute] = useState([]);
const getRute = async () => {
const response = await fetch('http://localhost:8080/rute');
const data = await response.json();
// console.log(data); // [{id:"1", name:"AAA"}, {id: "2", name: "BBB"}]
setRute(data);
// console.log(rute); // [] ===> why is this empty?
}
}
any help is appreciated
useState is asynchronous, so you won't see changes after setRute. You need to wait for the component re-rendered completely
const MasterRute = () => {
const [rute, setRute] = useState([]);
const getRute = async () => {
const response = await fetch('http://localhost:8080/rute');
const data = await response.json();
// console.log(data); // [{id:"1", name:"AAA"}, {id: "2", name: "BBB"}]
setRute(data);
}
console.log(rute); //data updated on rendering
}
You can check this article for a better understanding
If you still really want to see data after setRute. You can get the result within setTimeout
const MasterRute = () => {
const [rute, setRute] = useState([]);
const getRute = async () => {
const response = await fetch('http://localhost:8080/rute');
const data = await response.json();
// console.log(data); // [{id:"1", name:"AAA"}, {id: "2", name: "BBB"}]
setRute(data);
setTimeout(() => {
console.log(rute); //data updated
})
}
}
Data fetched successfully but my state does not change.
I initialize the state categories as an empty [] then I want to set it to the data I fetched. Response is OK and I can see the data in the console.
It is an object with one pair: categories:Array(14) which is what I am looking for.
const [categories,setCategories] = useState([])
useEffect(() => {
const fetchMeals = async () => {
const res = await fetch(
"https://www.themealdb.com/api/json/v1/1/categories.php"
);
const data = await res.json();
console.log(data.categories); /*array (14)*/
setCategories(data.categories.map((cat) => cat.strCategory));
console.log(categories); /*empty array*/
};
fetchMeals();
},[]);
Why doesn't work?
setState is async like operation so you would never see updated state synchronously (after invoking setState).
You can do alternatively:
const updatedCategiories = data.categories.map((cat) => cat.strCategory);
setCategories(updatedCategiories);
console.log(updatedCategiories);
I'm working on edit/update function and what I want to do is to save the response of axios.get to setState right after I click the a specific row from the table.
const [dataSystem, setdataSystem] = useState([])
const [systemDetails, setsystemDetails] = ({
ID: '',
.....,
})
const getAllSystems = async() => {
......
}
const getDependentSystems = async() => { //this is being triggered by a handleselectedSysDep when a row selected
const response = await axios.get('/API' + ID) //ID is being passed by handleselectedSysDep from the selected row
console.log('LIST OF SYSTEM', response.data)
setdataSystem(response.data)
}
const [selectedSystemID, setselectedSysID] = useState('');
let selectedSysID;
const handleselectedSysDep = (ID, action) => { //will be triggered when a row selected
setsystemDetails(ID);
selectedSysID = {...selectedSystemID, 'ID': ID.ID}
getDependentSystems();
}
useEffect(() => {
getAllSystems ();
})
What I want is when getDependentSystems() was called, setdataSystem will be populated right away to display the response data of the API since I'm doing edit. Hope you can help me with this.
Here's the result of console.log('LIST OF SYSTEM', response.data)
Thank you
This looks like a good use-case to use the useEffect hook to watch for changes in systemDetails and execute your getDependentSystems() side-effect.
For example
const [dataSystem, setDataSystem] = useState([])
const [systemDetails, setSystemDetails] = ({
ID: '',
//.....,
})
const handleselectedSysDep = (ID, action) => {
setSystemDetails(ID); // assuming `ID` is an object
}
// Now add an effect to watch for `systemDetails` changes
useEffect(() => {
if (systemDetails.ID) {
axios.get(`/API/${systemDetails.ID}`).then(({ data }) => setDataSystem(data))
}
}, [ systemDetails ]) // 👈 note the dependencies array
You can also use this answer to only fire the useEffect hook after the initial render.
FYI, if you only want getAllSystems() to execute once when your component is mounted, you should use
useEffect(() => {
getAllSystems()
}, []) // 👈 note the empty array