Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

NextJS adding item to element and rendering in tailwind select keeps throwing errors

Im having a bit of an issue displaying dynamic values into a select box in NextJS

I am getting values from an API endpoint, making sure that data is returned and then displaying it in a select box as below, BUT i want to add an element to the top of the ‘teams’ array and then make sure on page load that the new element is displayed first.

I have tried adding the following bit of code below and above the api call, but it keeps returning errors

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const newData = {id: 1, team_name: 'Personal'}
teams.push(newData)
setSelected(newData[0])
Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

I have also tried adding a useEffect hook and then setting the selected, but this also returns errors.

Nothing I do seems to let me do this.

Any help would be amazing

const Create () => {
    const [selected, setSelected] = useState()

    const { data: teams, error, mutate } = useSWR('/teams', () => 
        axios.get('/teams')
            .then(response => response.data.data)
        )

    if (!teams) {
        return (<LoadPageSpinner />)
    }

    return (
        <>
            <Listbox value={selected} onChange={setSelected}>
                {({ open }) => (
                    <>
                        <Listbox.Label className="block text-sm font-medium leading-6 text-gray-900">Assigned to</Listbox.Label>
                        <div className="relative mt-2">
                            <Listbox.Button className="relative w-full cursor-default rounded-md bg-white py-1.5 pl-3 pr-10 text-left text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-600 sm:text-sm sm:leading-6">
                                <span className="block truncate">{selected}</span>
                                <span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
                                    <ChevronUpDownIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
                                </span>
                            </Listbox.Button>

                            <Transition
                                show={open}
                                as={Fragment}
                                leave="transition ease-in duration-100"
                                leaveFrom="opacity-100"
                                leaveTo="opacity-0"
                            >
                                <Listbox.Options className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
                                    {teams.map((team) => (
                                        <Listbox.Option
                                            key={team.id}
                                            className={({ active }) =>
                                                classNames(
                                                    active ? 'bg-indigo-600 text-white' : 'text-gray-900',
                                                    'relative cursor-default select-none py-2 pl-3 pr-9'
                                                )
                                            }
                                            value={team.team_name}
                                        >
                                            {({ selected, active }) => (
                                                <>
                                                    <span className={classNames(selected ? 'font-semibold' : 'font-normal', 'block truncate')}>
                                                        {team.team_name}
                                                    </span>

                                                    {selected ? (
                                                        <span
                                                            className={classNames(
                                                                active ? 'text-white' : 'text-indigo-600',
                                                                'absolute inset-y-0 right-0 flex items-center pr-4'
                                                            )}
                                                        >
                                                            <CheckIcon className="h-5 w-5" aria-hidden="true" />
                                                        </span>
                                                    ) : null}
                                                </>
                                            )}
                                        </Listbox.Option>
                                    ))}
                                </Listbox.Options>
                            </Transition>
                        </div>
                    </>
                )}
            </Listbox>
        </>
    )
}



>Solution :

This should do it:

const personal = { id: 1, team_name: 'Personal' }
const {
  data: teams,
  error,
  mutate
} = useSWR('/teams', () =>
  axios.get('/teams').then((response) => [personal, ...response.data.data])
)

I’m placing the extra item in a new array containing it and everything in the response.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading