Factor out input to isolate component updates

This commit is contained in:
David Granado 2022-01-27 22:20:03 -06:00 committed by Thomas Zarebczan
parent 5048c460f1
commit 652d98f6c6
2 changed files with 39 additions and 14 deletions

View file

@ -0,0 +1,36 @@
// @flow
import React, { useEffect, useState } from 'react';
import Icon from 'component/common/icon';
import useDebounce from 'effects/use-debounce';
const FILTER_DEBOUNCE_MS = 300;
interface Props {
icon?: string;
value?: string;
placeholder?: string;
onChange: (newValue: string) => any;
}
export default function DebouncedInput(props: Props) {
const { icon, value = '', placeholder = '', onChange } = props;
const [rawValue, setRawValue] = useState(value);
const debouncedValue: string = useDebounce(rawValue, FILTER_DEBOUNCE_MS);
useEffect(() => {
onChange(debouncedValue);
}, [onChange, debouncedValue]);
return (
<div className="wunderbar">
{icon && <Icon icon={icon} />}
<input
className="wunderbar__input"
spellCheck={false}
placeholder={placeholder}
value={rawValue}
onChange={(e) => setRawValue(e.target.value.trim())}
/>
</div>
);
}

View file

@ -8,15 +8,14 @@ import Button from 'component/button';
import classnames from 'classnames'; import classnames from 'classnames';
import Icon from 'component/common/icon'; import Icon from 'component/common/icon';
import NotificationBubble from 'component/notificationBubble'; import NotificationBubble from 'component/notificationBubble';
import DebouncedInput from 'component/common/debounced-input';
import I18nMessage from 'component/i18nMessage'; import I18nMessage from 'component/i18nMessage';
import ChannelThumbnail from 'component/channelThumbnail'; import ChannelThumbnail from 'component/channelThumbnail';
import useDebounce from 'effects/use-debounce';
import { useIsMobile, useIsLargeScreen } from 'effects/use-screensize'; import { useIsMobile, useIsLargeScreen } from 'effects/use-screensize';
import { GetLinksData } from 'util/buildHomepage'; import { GetLinksData } from 'util/buildHomepage';
import { DOMAIN, ENABLE_UI_NOTIFICATIONS, ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM } from 'config'; import { DOMAIN, ENABLE_UI_NOTIFICATIONS, ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM } from 'config';
const FOLLOWED_ITEM_INITIAL_LIMIT = 10; const FOLLOWED_ITEM_INITIAL_LIMIT = 10;
const FILTER_DEBOUNCE_MS = 300;
type SideNavLink = { type SideNavLink = {
title: string, title: string,
@ -252,8 +251,7 @@ function SideNavigation(props: Props) {
const showSubscriptionSection = shouldRenderLargeMenu && isPersonalized && subscriptions && subscriptions.length > 0; const showSubscriptionSection = shouldRenderLargeMenu && isPersonalized && subscriptions && subscriptions.length > 0;
const showTagSection = sidebarOpen && isPersonalized && followedTags && followedTags.length; const showTagSection = sidebarOpen && isPersonalized && followedTags && followedTags.length;
const [rawSubscriptionFilter, setRawSubscriptionFilter] = React.useState(''); const [subscriptionFilter, setSubscriptionFilter] = React.useState('');
const subscriptionFilter: string = useDebounce(rawSubscriptionFilter, FILTER_DEBOUNCE_MS);
const filteredSubscriptions = subscriptions.filter( const filteredSubscriptions = subscriptions.filter(
(sub) => !subscriptionFilter || sub.channelName.toLowerCase().includes(subscriptionFilter) (sub) => !subscriptionFilter || sub.channelName.toLowerCase().includes(subscriptionFilter)
@ -307,16 +305,7 @@ function SideNavigation(props: Props) {
<> <>
<ul className="navigation__secondary navigation-links"> <ul className="navigation__secondary navigation-links">
<li className="navigation-item"> <li className="navigation-item">
<div className="wunderbar"> <DebouncedInput icon={ICONS.SEARCH} placeholder={__('Filter')} onChange={setSubscriptionFilter} />
<Icon icon={ICONS.SEARCH} />
<input
className="wunderbar__input"
spellCheck={false}
placeholder={__('Filter')}
value={rawSubscriptionFilter}
onChange={(e) => setRawSubscriptionFilter(e.target.value.trim())}
/>
</div>
</li> </li>
{displayedSubscriptions.map((subscription) => ( {displayedSubscriptions.map((subscription) => (
<SubscriptionListItem key={subscription.uri} subscription={subscription} /> <SubscriptionListItem key={subscription.uri} subscription={subscription} />