stevefrenzel
stevefrenzel

Reputation: 35

How to keep track of selected component?

I'm working on a coding challenge and I'm having problems to navigate back and forth between my components. Here's what a very simplified version of my parent component looks like:

import React, { useState } from 'react';

function App() {
  const [component, setComponent] = useState({
    shoppingBasket: true,
    contactDetails: false,
    paymentOptions: false,
    checkout: false,
    summary: false
  });

  const switchState = input => {
    const { name, value } = input.target;
    setComponent({
      ...component,
      [name]: value
    });
  };

  return (
  <>
    {
      component.shoppingBasket && 
      <ShoppingBasket
        shoppingBasket={component.shoppingBasket}
        switchState={switchState}
      />
    }
    {
      component.contactDetails && 
      <ContactDetails
        contactDetails={component.contactDetails}
        switchState={switchState}
      />
    }
    {
      component.paymentOptions && 
      <PaymentOptions
        paymentOptions={component.paymentOptions}
        switchState={switchState}
      />
    }
    {
      component.checkout && 
      <Checkout
        checkout={component.checkout}
        switchState={switchState}
      />
    }
    {
      component.summary && 
      <Summary
        summary={component.summary}
        switchState={switchState}
      />
    }
  </>
  );
}

export default App;

It's supposed to be the checkout screen of an e-commerce page and it starts with the <ShoppingBasket /> component. When clicking "Continue", it shows the next component, when clicking "Back" it goes back to the previous one. They should appear in the order shown in the code.

My first attempt was to show the next component only when the previous one(s) evaluate true but at the end it was showing all of the components, so that didn't work. Note: I passed the switchState function and the respective state as prop to the child component.

I guess the smartest way is to show only the component that is currently selected but how do I do that? I assume working with IDs?

And would it be still necessary to keep track of the previous components evaluating to true, when it's only showing the selected one anyway?


SOLUTION:

Parent component (simplified but working):

import React, { useState } from 'react';

// COMPONENTS
import ShoppingBasket from './components/ShoppingBasket';
import PaymentOptions from './components/PaymentOptions';
import ContactDetails from './components/ContactDetails';
import Checkout from './components/Checkout';
import Summary from './components/Summary';

export default function App() {
  const [component, setComponent] = useState(0);
  const switchComponent = (index) => {
    setComponent(index);
  };

  return (
    <>
      {
        {
          0: <ShoppingBasket switchComponent={switchComponent} />,
          1: <ContactDetails switchComponent={switchComponent} />,
          2: <PaymentOptions switchComponent={switchComponent} />,
          3: <Checkout switchComponent={switchComponent} />,
          4: <Summary />,
        }[component]
      }
    </>
  );
}

Child component with index 3 (also simplified):

import React from 'react';

export default function Checkout({ switchComponent }) {
  return (
    <>
      <button onClick={() => switchComponent(2)}>BACK</button>
      <button onClick={() => switchComponent(4)}>CONTINUE</button>
    </>
  );
}

Upvotes: 0

Views: 96

Answers (2)

Nassim Mesdour
Nassim Mesdour

Reputation: 176

ShoppingBasket.js

const ShoppingBasket = props => {

  return (
    // your ShoppingBasket component .....
  )

}

** ContactDetails.js**

const ContactDetails = props => {

  return (
    // your ContactDetails component .....
  )

}

....... the same for other components

App.js

import React, { useState } from 'react';

function App() {

const [component, setComponent] = useState(0);

const switchComponent = index => {
    setComponent(index);
};

return (
    <>
        {
            // this act like switch case js function
            // 
            {
                0:
                    (<ShoppingBasket/>),
                1:
                    (<ContactDetails/>),
                2:
                    (<PaymentOptions/>),
                3:
                    (<Checkout/>),
                4:
                    (<Summary/>)
            }[component]
        }

  // navigation buttons .... always visible
      <NavigateButtons 
         componentIndex={component}
         switchState={switchComponent} 
      /> 
    </>
);

}

export default App;

----------------------------------***----------------

Note : make sure the buttons next and previous are just one splited component so you can use it in diffrent other components

const NavigateButtons = (props) => ( 
<div>
   <Button  
      disabled={componentIndex == 4} 
      onClick={()=> props.switchState(componentIndex + 1)}>next
      </Button>
   <Button 
       disabled={componentIndex == 0}
       onClick={()=> props.switchState(componentIndex - 1)}>previous
       </Button>
</div>
)

Upvotes: 0

Nassim Mesdour
Nassim Mesdour

Reputation: 176

Update:

import React, { useState } from 'react';

function App() {

    const [component, setComponent] = useState(0);

    const switchComponent = index => {
        setComponent(index);
    };

    return (
        <>
            {
                // this act like switch case js function
                {
                    0:
                        (<ShoppingBasket
                            //shoppingBasket={component.shoppingBasket} // no need for this 
                            componentIndex={component}
                            switchState={switchComponent}
                        />),
                    1:
                        (<ContactDetails
                            // contactDetails={component.contactDetails}
                            componentIndex={component}
                            switchState={switchComponent}
                        />),
                    2:
                        (<PaymentOptions
                            // paymentOptions={component.paymentOptions}
                            componentIndex={component}
                            switchState={switchComponent}
                        />),
                    3:
                        (<Checkout
                            // checkout={component.checkout}
                            componentIndex={component}
                            switchState={switchComponent}
                        />),
                    4:
                        (<Summary
                            // summary={component.summary}
                            componentIndex={component}
                            switchState={switchComponent}
                        />)
                }[component]
            }
        </>
    );

}

export default App;

Upvotes: 1

Related Questions