useState hook not initialising with correct value: Array

PeteG :

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"
            />
    );
Vencovsky :

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])

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=11939&siteId=1