UseState multiple initial states

Viewed 76

I'm trying to initialize a constant variable which may either be used as a string or an array of strings depending on a prop that my component is receiving.

I'm trying to initialize it as

const [selectedOptions, setSelectedOptions] = useState<string[] | string>([]);

I realized that this is the incorrect way as this identifies the state as string[] | string rather than string[] or string. How should I go about initializing it instead?

1 Answers

I think it does exactly what you want. See the following example:

const [selectedOptions, setSelectedOptions] = useState<string[] | string>([]);

const arrayState: string[] = selectedOptions;

As expected, Typescript throws the following Error:

Type 'string | string[]' is not assignable to type 'string[]'.
  Type 'string' is not assignable to type 'string[]'.(2322)

The same happens with a string variable (just the other way around):

const stringState: string = selectedOptions;

If you've got different Child-Components, with props that expect different types, the following Snippet should be helpful.

import React, {useState} from 'react';

const SelectionSet = () => {
    const [selectedOptions, setSelectedOptions] = useState<string[] | string>([]);


    if(Array.isArray(selectedOptions)) {
        const arrayState: string[] = selectedOptions;
        return <ComponentA arrayProp={arrayState} />
    } 
    
    
    const stringState: string = selectedOptions;
    
    return <ComponentB stringProp={stringState} />        
}

The variables are just there for an explanatory reason. You could also set the props direclty by using the selectedOptions state.

On the other hand, if you want to use the selectedOptions-state always on the same child component, something like the following lines might be a solution:

const SelectionSet = () => {
    const [selectedOptions, setSelectedOptions] = useState<string[] | string>([]);

    // note the negation 
    if(!Array.isArray(selectedOptions)) {
        return <ComponentC stringProp={selectedOptions} />        
    } 
    
    
    return selectedOptions.map((option, key) => {
        return <ComponentC stringProp={option} key={key} />        
    });    
}
Related