Why doesn't it assign a value to state? I don't quite understand why the first time it doesn't assign me a value, while the second time it is as it should be. I need to do a setState in the dbRef function because the outside does not see the values. What can I do so I can assign a value more times?
Below is the code with which I tried to assign values
import { useState, useEffect } from "react";
import { dbRefMinMax, dbRefHist} from "./firebase";
import { Line } from 'react-chartjs-3';
function Teststate () {
const[state, setState] = useState ({
d6:null,
Max6:null,
Min6:null,
d7:null,
Max7:null,
Min7:null,
labelMin:null,
labelMax:null,
Click:null
})
function handleClick(){
setState({
Click : 'Temperature'
});
}
function handleClick2(){
setState({
Click : 'Pressure'
})
}
useEffect(()=>{
dbRefHist.limitToLast(6).on("value", snapshot => {
var history = snapshot.val();
var date6=Object.values(history)[5].date
var tempMax6=Object.values(history)[5].tempmax
var tempMin6=Object.values(history)[5].tempmin
var pressMax6=Object.values(history)[5].pressuremax
var pressMin6=Object.values(history)[5].pressuremin
var dd = date6.split("-")[2].split(" ")[0];
var mm = date6.split("-")[1].padStart(2, "0");
var day6=dd '.' mm
setState({
d6:day6,
Min6:tempMin6,
Max6:tempMax6
})
console.log(state.d6)
if (state.Click==='Pressure' ||state.Click===null){
setState({
Max6:pressMax6,
Min6:pressMin6,
labelMin:"Ciśnienie minimalne",
labelMax:"Ciśnienie maksymalne"
})
}else if (state.Click==='Temperature'){
setState({
Max6:tempMax6,
Min6:tempMin6,
labelMin:"Temperatura minimalna",
labelMax:"Temperatura maksymalna"
})
}
})
dbRefMinMax.on("value", snapshot => {
var minmax = snapshot.val();
var date7=minmax.date
var tempMax7=minmax.tempmax
var tempMin7=minmax.tempmin
var pressMax7=minmax.pressuremax
var pressMin7=minmax.pressuremin
var [year,month, day,] = date7.split('-');
var dd = date7.split("-")[2].split(" ")[0];
var mm = date7.split("-")[1].padStart(2, "0");
date7=dd '.' mm
setState({
d7:date7,
Min7:tempMin7,
Max7:tempMax7
})
console.log(state.d7)
if (state.Click==='Pressure' ||state.Click===null){
setState({
Max7:pressMax7,
Min7:pressMin7,
})
}else if (state.Click==='Temperature'){
setState({
Max7:tempMax7,
Min7:tempMin7,
})
}
})
},[]);
return (
<div>
<Line redraw={true}
data={{labels: [state.d1, state.d2, state.d3, state.d4, state.d5, state.d6, state.d7],
datasets: [
{
label: [state.labelMin],
data: [11, 12, 12,13, 23, 23,23],
fill: false,
// backgroundColor: "rgba(75,192,192,0.2)",
borderColor: "#129FE5"
},
{
label: state.labelMax,
data: [22, 33, 44, 11, 22, 22, 11],
fill: false,
borderColor: "rgba(227,22,22,1)"
}
]}}
/>
<div>
<button type="button" className="button" onClick={handleClick}>Temperatura</button>
<button className="button" type="button" onClick={handleClick2}><span className="text">Ciśnienie</span></button>
</div>
<p>{state.Click}</p>
<p>{state.Max7}</p>
</div>
);
}
Below is the code that shows what's really going on, it only displays state.d7 - as if it can only do one setState and chooses the last one
function Teststate2 () {
const[state, setState] = useState ({
})
useEffect(()=>{
var date6='12.11'
setState({
d6 : date6
})
var date7='13.11'
setState({
d7 : date7
})
},[]);
return (
<div>
<p>{state.Click}</p>
<p>{state.d7}</p>
<p>{state.d6}</p>
</div>
);
}
CodePudding user response:
If I understand correctly, you expect console.log(state.d6)
to log Object.values(history)[5].date
. However, the first time, it (probably) logs null
.
This is because state is only updated for the next render.
That means that
const [counter, setCounter] = useState(0);
console.log(counter); // will yield 0 at first render, 1 at second, 2 at third, etc
setCounter(counter 1);
console.log(counter); // will always yield the same as first console.log(counter)
CodePudding user response:
State updates are batched and take place after the function execution
function Teststate2 () {
const[state, setState] = useState ({
})
useEffect(() => {
// updates will be batched/queued
var date6='12.11'
setState({
d6 : date6
})
// will replace all previous state
// { d6: '12.11' }
var date7='13.11'
// replaces the previous state
setState({
d7 : date7
})
// { d7: '13.11' }
// possible options
// either update state at once
setState({
d6 : date6,
d7 : date7
});
// { d6: '12.11', d7: '13.11' }
// use state updater
setState(existinState => ({
...existinState
d6 : date6,
d7 : date7
});
// { ///other state props
// d6: '12.11',
// d7: '13.11'
// }
// even this should work as per the new docs
setState(s => ({
...s,
d6 : date6
})
setState(s => ({
...s,
d7 : date7
})
// { ///other state props
// d6: '12.11',
// d7: '13.11'
// }
},[]);
return (
<div>
<p>{state.Click}</p>
<p>{state.d7}</p>
<p>{state.d6}</p>
</div>
);
}
Hope it helps you sort out the actual problem