I am passing an array 'defaults' into my panel component and then trying to set state hook 'selected option' to be equal to it. For some reason, the hook is setting an empty array instead.
component:
const Panel = ({ title, inputs, datepicker, identifiers, apiBase, isins, defaults = [], notes = "" }) => {
const [expand, setExpand] = useState(false);
const [date, setDate] = useState(new Date());
const [selectedOption, setSelectedOption] = useState([...defaults]);
const [dataError, setDataError] = useState(false);
const [errorMsg, setErrorMsg] = useState('');
const [errorCheckLoading, setErrorCheckLoading] = useState(false);
const toggleExpand = () => {
setExpand(!expand);
console.log(defaults);
console.log(selectedOption);
};
Just for testing, I have a couple of console logs in my toggle expand function so I can test the data passed in against the data set.
Output from console logs:
>(48) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…},
{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…},
{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
>[]
So I know the data comes in ok, just that it doesn't set in the hook.
I have also tried giving the hook initial values of defaults, and [defaults].
Now drawing a blank - any ideas?
Edit: this is the parent component supplying the defaults:
const Parent = () => {
const [all, setAll] = useState([]);
const [allLoadFailed, setAllLoadFailed] = useState(false);
const [defaults, setDefaults] = useState([]);
const [defaultsLoadFailed, setDefaultsLoadFailed] = useState(false);
useEffect(() => { loadData()}, []);
useEffect(() => { loadDefaultData()}, []);
const loadDefaultData = async () => {
try {
let defaultData = await GetDefaults();
setDefaults(defaultData.map(item => item = {value: item, label: item}));
} catch (_) {
setDefaultsLoadFailed(true);
}
};
const loadData = async () => {
try {
let iData = await GetAll();
let filteredIData = iData.filter(item => item);
setAll(filteredIData.map(item => item = {value: item, label: item}));
} catch (_) {
setAllLoadFailed(true);
}
};
return (
<Panel
title="Test"
isins={all}
defaults={defaults}
inputs
datepicker
identifiers
apiBase=""
notes="not yet complete"
key="2"
/>
);
I'm guessing here that defaults
is a value from api call?
This happens because in the initial render defaults = []
and useState
's first parameter only get the initial value, so when default
change to the correct data in the second render, the useState
already have the []
value.
What you should do is use useEffect
hook when defaults
change and set selectedOption
.
useEffect(() => {
setSelectedOption([...defaults])
}, [defaults, setSelectedOption])