简体   繁体   中英

All inputs in Next.js are causing a full re-render

I'm working on a Next.js app right now using version 12.1.5 , and I'm running into a really crazy bug. Every input component is causing a full re-render on every keystroke, leading to a loss of focus on the input. This applies to input , textarea , and even the @monaco-editor/react package. I had the same issue in Formik forms, and was weirdly able to solve the problem by switching to react-hook-form . But, I'm still seeing it on all of my components that accept keystrokes.

I've tried moving the component's value state up the tree, tried putting the state local to the component, and I've had absolutely no luck. This is what my input component looks like:

Input.tsx

import { forwardRef, InputHTMLAttributes, ReactNode, Ref } from 'react';

import * as LabelPrimitive from '@radix-ui/react-label';
import css from 'classnames';

import { Flex } from 'containers/flex/Flex';

import s from './Input.module.scss';

interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
  label?: string;
  showLabel?: boolean;
  icon?: ReactNode;
}

export const Input = forwardRef(
  (
    { showLabel, name, className, label, icon, ...rest }: InputProps,
    ref: Ref<HTMLInputElement>
  ) => {
    return (
      <Flex column className={css(s.input, className)}>
        {showLabel && (
          <LabelPrimitive.Label htmlFor={name} className={s.input__label}>
            {label}
          </LabelPrimitive.Label>
        )}
        <Flex alignCenter className={s.input__icon}>
          {icon && icon}
        </Flex>
        <input
          ref={ref}
          name={name}
          {...rest}
          className={css(s.input__field, icon && s.hasIcon)}
        />
      </Flex>
    );
  }
);

Input.displayName = 'Input';

If I implement a value like this:

TestComponent.tsx

import { useState } from 'react';
import { Input } from 'elements/input/Input';

export const TestComponent = () => {
  const [value, setValue] = useState('');
  return <Input value={value} onChange={setValue}/>;
};

Any time I try to type I lose focus. Again, this has happened on every implementation of inputs that I've tried outside of react-hook-form , and includes the @monaco-editor/react package.

Here, also, is my package.json in case I've got any issues with other packages.

package.json

{
  "name": "app",
  "version": "0.6.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "test": "jest",
    "test:watch": "jest --watch",
    "vercel:build": "prisma generate && prisma migrate deploy && next build",
    "dev:connect": "pscale connect veroskills development --port 3309",
    "shadow:connect": "pscale connect veroskills shadow --port 3309",
    "slicemachine": "start-slicemachine",
    "prepare": "husky install"
  },
  "dependencies": {
    "@hookform/resolvers": "^2.8.8",
    "@monaco-editor/react": "^4.4.4",
    "@next-auth/prisma-adapter": "^1.0.3",
    "@prisma/client": "^3.13.0",
    "@prismicio/client": "^6.4.2",
    "@prismicio/helpers": "^2.2.1",
    "@prismicio/next": "^0.1.2",
    "@prismicio/react": "^2.2.0",
    "@prismicio/slice-simulator-react": "^0.2.1",
    "@radix-ui/react-alert-dialog": "^0.1.7",
    "@radix-ui/react-checkbox": "^0.1.5",
    "@radix-ui/react-dialog": "^0.1.7",
    "@radix-ui/react-dropdown-menu": "^0.1.6",
    "@radix-ui/react-icons": "^1.1.0",
    "@radix-ui/react-label": "^0.1.5",
    "@radix-ui/react-progress": "^0.1.4",
    "@radix-ui/react-scroll-area": "^0.1.4",
    "@radix-ui/react-select": "^0.1.1",
    "@radix-ui/react-separator": "^0.1.4",
    "@radix-ui/react-switch": "^0.1.5",
    "@radix-ui/react-tabs": "^0.1.5",
    "@radix-ui/react-toast": "^0.1.1",
    "@radix-ui/react-toolbar": "^0.1.5",
    "@radix-ui/react-tooltip": "^0.1.7",
    "bcryptjs": "^2.4.3",
    "classnames": "^2.3.1",
    "dayjs": "^1.11.0",
    "next": "^12.1.5",
    "next-auth": "^4.3.1",
    "next-compose-plugins": "^2.2.1",
    "next-images": "^1.8.4",
    "next-react-svg": "^1.1.3",
    "node-mocks-http": "^1.11.0",
    "path": "^0.12.7",
    "plyr-react": "^3.2.1",
    "prismic-reactjs": "^1.3.4",
    "react": "^18.0.0",
    "react-code-blocks": "^0.0.9-0",
    "react-dom": "^18.0.0",
    "react-gravatar": "^2.6.3",
    "react-hook-form": "^7.30.0",
    "react-loading-skeleton": "^3.1.0",
    "react-select": "^5.2.2",
    "react-table": "^7.7.0",
    "react-use-keypress": "^1.3.1",
    "sass": "^1.50.0",
    "swr": "^1.3.0",
    "use-monaco": "^0.0.40",
    "yup": "^0.32.11"
  },
  "devDependencies": {
    "@prismicio/types": "^0.1.27",
    "@types/bcryptjs": "^2.4.2",
    "@types/jest": "^27.4.1",
    "@types/node": "17.0.21",
    "@types/react": "18.0.1",
    "@types/react-dom": "^18.0.0",
    "@types/react-gravatar": "^2.6.10",
    "@types/react-table": "^7.7.10",
    "@typescript-eslint/eslint-plugin": "^5.18.0",
    "eslint": "8.12.0",
    "eslint-config-next": "12.1.4",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-prettier": "^4.0.0",
    "husky": "^7.0.0",
    "jest": "^27.5.1",
    "lint-staged": "^12.3.7",
    "prettier": "^2.6.2",
    "prisma": "^3.13.0",
    "slice-machine-ui": "^0.3.7",
    "ts-jest": "^27.1.4",
    "turbo": "^1.2.4",
    "typescript": "^4.6.3"
  },
  "lint-staged": {
    "**/*.{js,jsx,ts,tsx}": [
      "yarn eslint --fix",
      "yarn prettier --write"
    ]
  }
}

I am completely at a loss here; does anyone have idea what the issue could be?

I've figured out my problem through some extensive debugging. I have a reusable Flex component that utilizes createElement to allow me to create a flex box of any element by passing in an element type- div , button , nav etc, and I use that component within my input component. Getting rid of my createElement function and replacing it with a simple div fixed the problem, so now I just need to refactor the Flex component to still allow for any element type.

All that to say, the Flex component was causing a full render whenever it's children changed. Off to correct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM