Skip to content

Instantly share code, notes, and snippets.

@AbdQaadir
Created June 25, 2021 20:57
Show Gist options
  • Save AbdQaadir/d1cfa02f3851aa464e230c00320f2f6f to your computer and use it in GitHub Desktop.
Save AbdQaadir/d1cfa02f3851aa464e230c00320f2f6f to your computer and use it in GitHub Desktop.
Lateef Quadri's Chameleon React technical exercise
/*
Prompt:
We have defined a basic dropdown via the Dropdown and DropdownItem components below, with example usage
in the ExampleNav component. The Dropdown and DropdownItem components have some problems, and also
have room for improvements (doesn't everything?) A couple items TODO here (make sure to explain with comments!)
0. How are you today? 😊
ANS: Doing great and trust you're as well.
1. Please fix any obvious issues you see with the dropdown.
ANS: Fixed <DropdownItem /> component to render items passed down.
2. Please then make improvements to the dropdown.
ANS: I don't know if this is an improvement, but I moved the components from using class based components to functional components.
This brings forth ease through the use of hooks and the elimination of constructor and manually attaching events within the constructor.
3. Consider the different ways that this dropdown might be used and what changes would
be neccessary to make it more flexible.
ANS: The children passed to <DropdownItem /> component could easily be passed down as a prop, and whenever a children is passed down; that means the Dropdown could also serve as a <Dropdown /> component. More of a nested dropdown component.
4. If we wanted to sync this dropdown selection to the server with
app.sync('PATCH', 'user', { dropdown_1_state: {true,false} }) where would this be included?
ANS: Not sure I get this question, but it could be placed in the useEffect hook and then listen to changes on a certain prop or state to update the server.
5. If we wanted to pass children (like this example) OR a Promise that resolves to an array of items
what changes should be made? (just a sentence or two or some code is ok).
ANS: In case where an array or a children needs to be passed down, I already handled the case so as to render a nested dropdown element.
PS: No need to worry about CSS.
*/
import React, { useState } from 'react';
import { render } from 'react-dom';
const Dropdown = (props) => {
const [isOpen, setIsOpen] = useState(false)
const toggle = () => {
setIsOpen((previousState) => !previousState);
}
const {label} = props;
return (
<div className="dropdown">
<button type="button" className="dropdown-button" id="dropdownButton" aria-haspopup="true" aria-expended={isOpen} onClick={toggle}>{label}</button>
<ul className={`${isOpen ? 'dropdown-open' : ''} dropdown-menu`} aria-labelledby="dropdownButton" role="menu">
{props.children}
</ul>
</div>
);
}
const DropdownItem = (props) => {
const hasChildren = props.children && Array.isArray(props.children);
if(hasChildren){
return (
<Dropdown>
{ hasChildren.map((item) => <DropdownItem href="/page2">{item}</DropdownItem>) }
</Dropdown>
)
}
return <a href={props.href}>{props.title}</a>
}
const ExampleNav = () => {
return (
<nav>
<a href="/page1">Page 1</a>
<Dropdown label="More items">
<DropdownItem title="Page 1" href="/page2" />
<DropdownItem title="Page 2" href="/page3" />
<DropdownItem title="Page 3" href="/page4" />
</Dropdown>
<Dropdown label="Even more items">
<DropdownItem title="Page 4" href="/page5" />
<DropdownItem title="Page 5" href="/page6" />
</Dropdown>
</nav>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment