I have a chart component in which specific lines can be shown/hidden. To keep track of which lines are active I keep an activeKeys
array in a state. Initially I get the key names from a function getKeys
that takes the array of data.
When I do this:
const defaultValue = getKeys(data)
console.log('defaultValue from keys', defaultValue)
const [activeKeys, setActiveKeys] = useState(defaultValue)
console.log('activeKeys', activeKeys)
First console log shows the correct keys:
["createdCount", "confirmedCount", "hasFeedbackCount"]
Second console log shows []
But if I do:
const defaultValue = ["createdCount", "confirmedCount","hasFeedbackCount"]
console.log('defaultValue', defaultValue)
const [activeKeys, setActiveKeys] = useState(defaultValue)
console.log('activeKeys', activeKeys)
First console log shows the same array:
["createdCount", "confirmedCount", "hasFeedbackCount"]
And activeKeys
shows the correct array:
["createdCount", "confirmedCount", "hasFeedbackCount"]
Is useState
broken or something? By the getKeys
is a simple function, no promise or anything like that. It looks like this:
const getKeys = (data: Props['data']): string[] => {
const reduced = data.reduce((acc, datum) => [...acc, ...Object.keys(datum.lines)] as any, [])
const setted = new Set(reduced)
const arrayed = Array.from(setted)
return arrayed
}
The shape of Props['data']
is:
data: {
date: string
lines: Partial<Record<string, number>>
}[]
I had this same problem. It is correct that there is not a bug with React.useState
.
The issue here is that your component is being mounted and calculating the empty array as the default value. Subsequently your "default value" is changing to your expected default value but the React.useState
already has a default value of empty array.
To fix this you'll need to avoid mounting the component until the desired default value is available. Alternatively you could probably do something like using a React.useEffect
hook to look for a change in props and call the setter (second item in the array) of the React.useState
output.
There doesn't seem to be a problem with useState
.
As per React DOCs:
What do we pass to useState as an argument?
The only argument to the useState() Hook is the initial state. Unlike with classes, the state doesn’t have to be an object. We can keep a number or a string if that’s all we need. In our example, we just want a number for how many times the user clicked, so pass 0 as initial state for our variable. (If we wanted to store two different values in state, we would call useState() twice.)
So it's perfectly normal to pass an array of strings as initial state for useState
. Even if it's the result of a function. (see snippet below).
I couldn't reproduce your getKeys
function here on SO Snippet Editor, I suggest you further inspect that. Although this could also be a problem with the snippet builder that may not support some JS features.
NOTE: This is not a problem with useState
. Something else is going wrong. Try to submit a working example of the issue being reproduced.
function App() {
const someFunction = (x) => {
return x;
}
const data = ['A','B','C'];
const [state,setState] = React.useState(someFunction(data));
console.log(state);
return(
<div>{state.toString()}</div>
);
}
ReactDOM.render(<App/>,document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With