Skip to content

Instantly share code, notes, and snippets.

@Trend20
Last active March 28, 2023 12:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Trend20/15bb8c6f80e3ca8e01880dbf36787a18 to your computer and use it in GitHub Desktop.
Save Trend20/15bb8c6f80e3ca8e01880dbf36787a18 to your computer and use it in GitHub Desktop.
/*
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? 😊
1. Please fix any obvious issues you see with the dropdown.
2. Please then make improvements to the dropdown and make it a bit more React-y. Assume this was cobbled
together or brought in hastily from StackOverflow.
3. Given that this dropdown might form the basis of an Account picker, a searchable list of Product Tours, one
step of a flow to configure alerting, etc... Please explore with text or code the way you would approach this.
4. If we wanted to sync this dropdown selection to the server with
httpPatch('user', { [`dropdown-state-${key}`]: {true,false} }) where would this be included OR how best to
handle this (properties needing to be synced to the backend)?
5. Anything else to add here?
6. Unrelated to this, what is one new feature you would add to React?
I would use React hooks for functional components instead of the class components.
Hooks makes it easy to write clean code while managing state compared to the class components.
PS: No need to worry about CSS, actually making it "run" etc...
*/
import React, {PureComponent} from 'react';
import { httpPatch } from 'lib/http';
class Dropdown extends PureComponent {
// fix the constructor typo
constructor(props) {
super(props);
this.state = {
isOpen: false,
};
}
// use arrow function to bind the this context
toggle = () =>{
//const {isOpen} = this.state;
// fix the isOpen state by assinging the new state to the negation of the original state
//use previous state to update the state
this.setState((previousState) => ({
isOpen: !previousState.isOpen
}));
}
render() {
const {isOpen} = this.state;
// destructure children prop just like the label prop
const {label, children} = this.props;
return (
<div className="dropdown">
//fix the typo on the button from aria-expended to aria-expanded
<button type="button" className="dropdown-button" id="dropdownButton" aria-haspopup="true" aria-expanded={isOpen} onClick={this.toggle}>{label}</button>
<ul className={`${isOpen ? 'dropdown-open' : ''} dropdown-menu`} aria-labelledby="dropdownButton" role="menu">
{children}
</ul>
</div>
);
}
}
class DropdownItem extends PureComponent {
constructor(props){
super(props)
this.state={
}
}
// define a handle click function using the arrow function to automatically bind this
handleClick = () => {
const { href } = this.props;
httpPatch('user', { [`dropdown-state-${href}`]: true });
};
render() {
// destructure the props
const { href, children } = this.props;
// TODO implement me
// add a return for the component contents to be rendered
return (
<li>
<a href={href} onClick={this.handleClick}>
{children}
</a>
</li>
)
}
}
class ExampleNav extends PureComponent {
render() {
return (
<nav>
<a href="/page1">Page 1</a>
<Dropdown label="More items">
<DropdownItem href="/page2">Page 2</DropdownItem>
<DropdownItem href="/page3">Page 3</DropdownItem>
<DropdownItem href="/page4">Page 4</DropdownItem>
</Dropdown>
<Dropdown label="Even more items">
<DropdownItem href="/page5">Page 5</DropdownItem>
<DropdownItem href="/page9">Page 9</DropdownItem>
</Dropdown>
</nav>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment