Explorar el Código

fix(form): fix hydration error

was due to nested anchor tags
zyachel hace 2 años
padre
commit
8599ae2c5a

+ 8 - 10
src/components/card/CardResult.tsx

@@ -25,16 +25,14 @@ const CardResult = ({ link, name, image, showImage, children, ...rest }: Props)
     );
 
   return (
-    <Card hoverable {...rest}>
-      <Link href={link}>
-        <a className={`${styles.item} ${!showImage && styles.sansImage}`}>
-          <div className={styles.imgContainer}>{ImageComponent}</div>
-          <div className={styles.info}>
-            <p className={`heading ${styles.heading}`}>{name}</p>
-            {children}
-          </div>
-        </a>
-      </Link>
+    <Card hoverable {...rest} className={`${styles.item} ${!showImage && styles.sansImage}`}>
+      <div className={styles.imgContainer}>{ImageComponent}</div>
+      <div className={styles.info}>
+        <Link href={link}>
+          <a className={`heading ${styles.heading}`}>{name}</a>
+        </Link>
+        {children}
+      </div>
     </Card>
   );
 };

+ 32 - 34
src/components/forms/find/index.tsx

@@ -5,41 +5,16 @@ import { QueryTypes } from 'src/interfaces/shared/search';
 import { resultTypes, resultTitleTypes } from 'src/utils/constants/find';
 import styles from 'src/styles/modules/components/form/find.module.scss';
 
-/**
- * helper function to render similar radio btns. saves from boilerplate.
- * @param data radio btn obj
- * @param parentClass class under which radio input and label will be
- * @returns JSX array of radios
- */
-const renderRadioBtns = (
-  data: typeof resultTypes | typeof resultTitleTypes,
-  parentClass: string
-) => {
-  return data.types.map(({ name, val }) => (
-    <p className={parentClass} key={val}>
-      <input
-        type='radio'
-        name={data.key}
-        id={`${data.key}:${val}`}
-        value={val}
-        className='visually-hidden'
-      />
-      <label htmlFor={`${data.key}:${val}`}>{name}</label>
-    </p>
-  ));
-};
-
 type Props = {
   className?: string;
 };
 
-// MAIN FUNCTION
 const Form = ({ className }: Props) => {
   const router = useRouter();
   const formRef = useRef<HTMLFormElement>(null);
   const [isDisabled, setIsDisabled] = useState(false);
 
-  // title types can't be selected unless type selected is 'title'. below is the logic for disabling/enabling titleTypes.
+  // title types can't be selected unless type selected is 'title'
   const typesChangeHandler: ChangeEventHandler<HTMLFieldSetElement> = e => {
     const el = e.target as unknown as HTMLInputElement; // we have only radios that'll fire change event.
     const value = el.value as QueryTypes;
@@ -60,6 +35,7 @@ const Form = ({ className }: Props) => {
     const queryStr = cleanQueryStr(entries);
 
     if (query) router.push(`/find?${queryStr}`);
+    else setIsDisabled(false);
     formEl.reset();
   };
 
@@ -87,22 +63,20 @@ const Form = ({ className }: Props) => {
           name='q'
           placeholder='movies, people...'
           className={styles.searchbar__input}
+          required
+          minLength={2}
         />
         <label className='visually-hidden' htmlFor='searchbar'>
           Search for anything
         </label>
       </p>
       <fieldset className={styles.types} onChange={typesChangeHandler}>
-        <legend className={`heading ${styles.types__heading}`}>
-          Filter by Type
-        </legend>
-        {renderRadioBtns(resultTypes, styles.type)}
+        <legend className={`heading ${styles.types__heading}`}>Filter by Type</legend>
+        <RadioBtns data={resultTypes} className={styles.type} />
       </fieldset>
       <fieldset className={styles.titleTypes} disabled={isDisabled}>
-        <legend className={`heading ${styles.titleTypes__heading}`}>
-          Filter by Title Type
-        </legend>
-        {renderRadioBtns(resultTitleTypes, styles.titleType)}
+        <legend className={`heading ${styles.titleTypes__heading}`}>Filter by Title Type</legend>
+        <RadioBtns data={resultTitleTypes} className={styles.titleType} />
       </fieldset>
       <p className={styles.exact}>
         <label htmlFor='exact'>Exact Matches</label>
@@ -120,4 +94,28 @@ const Form = ({ className }: Props) => {
   );
 };
 
+const RadioBtns = ({
+  data,
+  className,
+}: {
+  data: typeof resultTypes | typeof resultTitleTypes;
+  className: string;
+}) => (
+  <>
+    {data.types.map(({ name, val }) => (
+      <p className={className} key={val}>
+        <input
+          type='radio'
+          name={data.key}
+          id={`${data.key}:${val}`}
+          value={val}
+          className='visually-hidden'
+        />
+        <label htmlFor={`${data.key}:${val}`}>{name}</label>
+      </p>
+    ))}
+  </>
+);
+
+
 export default Form;

+ 0 - 3
src/styles/modules/components/card/card-result.module.scss

@@ -7,9 +7,6 @@
   display: grid;
   grid-template-columns: var(--width) auto;
 
-  text-decoration: none;
-  color: inherit;
-
   @include helper.bp('bp-450') {
     --height: 15rem;
     grid-template-columns: auto;