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

React update array prop from child to parent

Hello I am struggling to properly update my state from my child component to my parent.
Basically I am trying to set the current state to true onclick.

This is my parent component:

export default function Layout({ children }: Props) {
  const [navigation, setNavigation] = useState([
    { name: 'Dashboard', href: '/', icon: HomeIcon, current: true },
    { name: 'Create Fact', href: '/facts/create', icon: UsersIcon, current: false },
    { name: 'Documents', href: '/documents', icon: InboxIcon, current: false }
  ])

  return (
    <>
      <Sidebar navigation={navigation} setNavigation={setNavigation} />

This is my child Component (Sidebar)

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

type Props = {
  navigation: Array<{
    name: string
    href: string
    icon: any
    current: boolean
  }>
  setNavigation: (
    navigation: Array<{
      name: string
      href: string
      icon: any
      current: boolean
    }>
  ) => void
}

const Sidebar = ({navigation, setNavigation}: Props) => {
  const router = useRouter()
  const toggleNavigation = (name: string) => {
    // todo: Here I would like to properly update the state with the current selected navigation item (current)
    const newNavigation = navigation.map(nav => {
      if (nav.name === name) {
          nav.current = true
        return nav
      }
    })
  }

  return (
    <nav className="flex-1 px-2 pb-4 space-y-1">
      {navigation.map(item => (
        <span
          onClick={() => toggleNavigation(item.name)}

>Solution :

There are three problems:

  1. You never call setNavigation with your new array.

  2. You don’t clear current on the formerly-current item.

  3. Although you’re creating a new array, you’re reusing the objects within it, even when you change them, which is against the Do Not Modify State Directly rule.

To fix all three (see *** comments):

const toggleNavigation = (name: string) => {
    const newNavigation = navigation.map(nav => {
        if (nav.name === name) {
            // *** #3 Create a *new* object with the updated state
            nav = {...nav, current: true};
        } else if (nav.current) { // *** #2 make the old current no longer current
            nav = {...nav, current: false};
        }
        return nav;
    });
    // *** #1 Do the call to set the navigation
    setNavigation(newNavigation);
};

Separately, though, I would suggest separating navigation out into two things:

  • The set of navigation objects.
  • The name of the current navigation item.

Then setting the navigation item is just setting a new string, not creating a whole new array with an updated object in it.

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