如何修复“警告:useLayoutEffect 在服务器上什么都不做"? [英] How to fix the "Warning: useLayoutEffect does nothing on the server"?

查看:64
本文介绍了如何修复“警告:useLayoutEffect 在服务器上什么都不做"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是完整的错误:

警告:useLayoutEffect 在服务器上什么都不做,因为它的效果无法编码到服务器渲染器的输出格式中.这将导致初始的、非水合的 UI 和预期的用户界面.为了避免这种情况,useLayoutEffect 应该只用于只在客户端呈现的组件

Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client

      in ForwardRef(ButtonBase)
      in WithStyles(ForwardRef(ButtonBase))
      in ForwardRef(Button)
      in WithStyles(ForwardRef(Button))
      in form
      in div

我每次运行测试时都会得到它.这是我的测试

I get it every time I run my test. Heres my test

/* eslint-disable quotes */
import React from "react"
import { shallow, configure } from "enzyme"
import LoginForm from "../src/components/LoginForm"
import Button from "@material-ui/core/Button"
import Adapter from "enzyme-adapter-react-16"
import { render, fireEvent, cleanup } from "@testing-library/react"

configure({ adapter: new Adapter() })

describe("<LoginForm />", () => {
  let wrapper
  let usernameInput
  let passwordInput
  let signInButton

  // Create initial props that get passed into the component
  const initialProps = {
    location: {
      state: {
        from: {
          pathname: "/",
        },
      },
    },
  }

  // Unit testing
  describe("Unit tests", () => {
    // what to do before each test
    beforeEach(() => {
      // Render the login form component, pass in props. (Shallow method renders the component without its children, good for unit tests.)
      wrapper = shallow(<LoginForm {...initialProps} />)
      usernameInput = wrapper.find("#username")
      passwordInput = wrapper.find("#password")
      signInButton = wrapper.find(Button)
    })

    // what to do after each test
    afterEach(() => {
      jest.clearAllMocks()
    })

    // UI Integrity test
    it("should match the snapshot", () => {
      // snapshots are text references of the html of the rendered component.
      expect(wrapper.html()).toMatchSnapshot()
    })

    it("should have a username inputs", () => {
      expect(usernameInput.length).toEqual(1)
    })

    it("should have the expected props on the username field", () => {
      expect(usernameInput.props()).toEqual({
        id: "username",
        name: "username",
        value: "",
        type: "username",
        onChange: expect.any(Function),
        required: true,
      })
    })

    it("should have a password field", () => {
      expect(passwordInput.length).toEqual(1)
    })

    it("should have the expected props on the password field", () => {
      expect(passwordInput.props()).toEqual({
        id: "password",
        name: "password",
        value: "",
        type: "password",
        onChange: expect.any(Function),
        required: true,
      })
    })

    it("should have a submit button", () => {
      expect(signInButton.length).toEqual(1)
    })

    it("should have the expected props on the button", () => {
      expect(signInButton.props()).toEqual({
        type: "button",
        variant: "contained",
        style: expect.objectContaining({
          marginTop: "10px",
        }),
        onClick: expect.any(Function),
        children: "Sign In",
      })
    })
  })

  // Integrations Testing
  describe("Integrations tests", () => {
    beforeEach(() => {
      // Render the login form component, pass in props. (render method renders the component with its children, good for integrations tests, uses react-test-library.)
      const { getByLabelText, getByText } = render(
        <LoginForm {...initialProps} />
      )
      usernameInput = getByLabelText(/Username/i)
      passwordInput = getByLabelText(/Password/i)
      signInButton = getByText("Sign In")
    })

    afterEach(cleanup)

    it("Username text change in onChange event", () => {
      expect(usernameInput.value).toBe("")

      fireEvent.change(usernameInput, { target: { value: "James" } })

      expect(usernameInput.value).toBe("James")
    })

    it("Password text change in onChange event", () => {
      expect(passwordInput.value).toBe("")

      fireEvent.change(passwordInput, { target: { value: "mypassword" } })

      expect(passwordInput.value).toBe("mypassword")
    })

    it("Test button submit", () => {
      const mockLogin = jest.fn()

      const button = shallow(<Button onClick={mockLogin} />)

      button.simulate("click")

      expect(mockLogin.mock.calls.length).toEqual(1)
    })
  })
})

我相信它与 material-ui 组件有关.我已经调查过了,这里有一个类似的问题 说这个问题与我的项目没有的依赖关系有关.所以我认为这与使用 useEffectLayout 的 material-ui 组件有关,并且由于某种原因,测试环境不喜欢那样.我用 yarn 和 jest yarn test 运行我的测试来运行测试套件.

I believe it has something to do with the material-ui component. I've looked into it, theres a similar question on here that says the issue has to do with a dependency that my project does not have. So I think it has to do with the material-ui component using useEffectLayout and the testing env doesnt like that for some reason. Im running my test with yarn and jest yarn test to run the test suite.

推荐答案

adding

import React from "react" 
React.useLayoutEffect = React.useEffect 

到我的前端/src/setupTests.js 测试文件是一种抑制开玩笑警告的方法.最终,这似乎是 Material-UI 组件在 Jest 上的问题.

to my frontend/src/setupTests.js test file is a way to suppress the jest warning. Ultimately, this looks to be an issue with Material-UI components having issues with Jest.

这篇关于如何修复“警告:useLayoutEffect 在服务器上什么都不做"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆