refactored Navbar component

This commit is contained in:
andres alcocer
2021-10-07 16:05:04 -04:00
parent 39b9995f82
commit 0bbbb9d5f3
4 changed files with 130 additions and 91 deletions

View File

@@ -1,108 +1,94 @@
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import _ from 'lodash';
import { withRouter } from 'react-router-dom';
import React, { useState, useEffect } from 'react'
import { NavLink } from 'react-router-dom'
import _ from 'lodash'
import { withRouter } from 'react-router-dom'
import axios from '../axios-movies';
import SearchLogo from '../static/images/search-icon.svg';
import NetflixLogo from '../static/images/Netflix_Logo_RGB.png';
import BellLogo from '../static/images/bell-logo.svg';
import DropdownArrow from '../static/images/drop-down-arrow.svg';
import DropdownContent from "../components/DropdownContent";
import { useScroll } from '../hooks/useScroll'
import { useDebounce } from '../hooks/useDebounce'
import axios from '../axios-movies'
import SearchLogo from '../static/images/search-icon.svg'
import NetflixLogo from '../static/images/Netflix_Logo_RGB.png'
import BellLogo from '../static/images/bell-logo.svg'
import DropdownArrow from '../static/images/drop-down-arrow.svg'
import DropdownContent from '../components/DropdownContent'
class Navbar extends Component {
constructor(props) {
super(props)
this.state = {
scrolling: false,
userInput: ''
const Navbar = (props) => {
const [userInput, setUserInput] = useState('')
const [scrollDimensions] = useScroll()
const { scrollY } = scrollDimensions
const debouncedUserInput = useDebounce(userInput, 500)
const onChange = async (event) => {
setUserInput(event.target.value)
}
useEffect(() => {
onSearchUserInputHandler(userInput)
if (debouncedUserInput) {
onSearchUserInputHandler(debouncedUserInput)
}
// use to debounce api call
this.makeAipCall = _.debounce(this.makeAipCall, 1000)
}
}, [debouncedUserInput])
componentDidMount() {
window.addEventListener('scroll', this.handleScroll);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll);
}
/** changes the scrolling state depending on the Y-position */
handleScroll = () => {
if (window.scrollY === 0) {
this.setState({ scrolling: false });
}
else if (window.scrollY > 50) {
this.setState({ scrolling: true });
}
}
onChange = async (event) => {
await this.setState({ userInput: event.target.value })
const { userInput } = this.state
await this.makeAipCall(userInput);
}
/** Make API call as soon as the user starts typing. */
makeAipCall = async (searchItem) => {
const onSearchUserInputHandler = async (searchItem) => {
if (searchItem.length === 0) {
this.props.history.push('/')
props.history.push('/')
return
}
const url = `/search/multi?api_key=${process.env.API_KEY}&language=en-US&include_adult=false&query=${searchItem}`;
const response = await axios.get(url);
const results = response.data.results;
this.props.history.push({
const url = `/search/multi?api_key=${process.env.API_KEY}&language=en-US&include_adult=false&query=${searchItem}`
const response = await axios.get(url)
const results = response.data.results
console.log('called api...')
props.history.push({
pathname: '/search',
movieRows: results,
userInput: searchItem
});
userInput: searchItem,
})
}
onLogoClick = () => {
// reset input state
this.setState({ userInput: '' })
const onLogoClick = () => {
setUserInput('')
}
render() {
const { scrolling } = this.state;
return (
<nav className={'navigation ' + (scrollY > 50 ? 'black' : '')}>
<ul className='navigation__container'>
<NavLink to='/' onClick={() => onLogoClick()}>
<img
className='navigation__container--logo'
src={NetflixLogo}
alt=''
/>
</NavLink>
<DropdownArrow className='navigation__container--downArrow-2'></DropdownArrow>
<div className='navigation__container-link pseudo-link'>Home</div>
<div className='navigation__container-link pseudo-link'>TV Shows</div>
<div className='navigation__container-link pseudo-link'>Movies</div>
<div className='navigation__container-link pseudo-link'>
Recently Added
</div>
<div className='navigation__container-link pseudo-link'>My List</div>
return (
<nav className={"navigation " + (scrolling ? "black" : "")} >
<ul className="navigation__container">
<NavLink to="/" onClick={() => this.onLogoClick()}>
<img className="navigation__container--logo" src={NetflixLogo} alt="" />
</NavLink>
<DropdownArrow className="navigation__container--downArrow-2"></DropdownArrow>
<div className="navigation__container-link pseudo-link">Home</div>
<div className="navigation__container-link pseudo-link">TV Shows</div>
<div className="navigation__container-link pseudo-link">Movies</div>
<div className="navigation__container-link pseudo-link">Recently Added</div>
<div className="navigation__container-link pseudo-link">My List</div>
<div className='navigation__container--left'>
<SearchLogo className='logo' />
<input
value={userInput}
onChange={(event) => onChange(event)}
className='navigation__container--left__input'
type='text'
placeholder='Title, genres, people'
/>
</div>
<div className="navigation__container--left">
<SearchLogo className="logo" />
<input
value={this.state.userInput}
onChange={() => this.onChange(event)}
className="navigation__container--left__input"
type="text"
placeholder="Title, genres, people" />
</div>
<div className='navigation__container-link pseudo-link'>KIDS</div>
<div className='navigation__container-link pseudo-link'>DVD</div>
<BellLogo className='navigation__container--bellLogo' />
<div className="navigation__container-link pseudo-link">KIDS</div>
<div className="navigation__container-link pseudo-link">DVD</div>
<BellLogo className="navigation__container--bellLogo" />
<DropdownContent />
<DropdownArrow className="navigation__container--downArrow" />
</ul>
</nav>
)
}
<DropdownContent />
<DropdownArrow className='navigation__container--downArrow' />
</ul>
</nav>
)
}
export default withRouter(Navbar);
export default withRouter(Navbar)

25
src/hooks/useDebounce.js Normal file
View File

@@ -0,0 +1,25 @@
import { useState, useEffect } from 'react'
export const useDebounce = (value, delay) => {
// State and setters for debounced value
const [debouncedValue, setDebouncedValue] = useState(value)
useEffect(
() => {
// Update debounced value after delay
const handler = setTimeout(() => {
setDebouncedValue(value)
}, delay)
// Cancel the timeout if value changes (also on delay change or unmount)
// This is how we prevent debounced value from updating if value is changed ...
// .. within the delay period. Timeout gets cleared and restarted.
return () => {
clearTimeout(handler)
}
},
[value, delay] // Only re-call effect if value or delay changes
)
return debouncedValue
}

26
src/hooks/useScroll.js Normal file
View File

@@ -0,0 +1,26 @@
import { useState, useEffect } from 'react'
const scrollY = window.scrollY || document.documentElement.scrollTop
const scrollX = window.scrollY || document.documentElement.scrollWidth
export const useScroll = () => {
const [scrollDimensions, setScrollDimensions] = useState({ scrollY, scrollX })
const deriveScrollDimensions = () => {
const scrollY = window.scrollY || document.documentElement.scrollTop
const scrollX = window.scrollY || document.documentElement.scrollWidth
setScrollDimensions({ scrollY, scrollX })
}
useEffect(() => {
deriveScrollDimensions()
window.addEventListener('scroll', deriveScrollDimensions)
return () => {
window.removeEventListener('resize', deriveScrollDimensions)
}
}, [])
return [scrollDimensions]
}

View File

@@ -1,9 +1,11 @@
import React from 'react';
export default function NotFound() {
const NotFound = () => {
return (
<div>
<h1>NOT FOUND</h1>
</div>
);
}
export default NotFound