1
votes

I built a controlled form component with hooks and used styled-components instead of a styles.css file. However every time I did a key press in an input field, focus was lost. After much investigation, I discovered that by reverting back to a styles.css file and abandoning styled-components, everything worked as expected. Is this a known problem with styled-components when using hooks?

UPDATED 4/7/2019

Here is example code. The first field has "input" changed to "Input" using the styled component. Focus is lost in that field on each click. The second field has no problem. Of course the form is rendered each time setFirstName() is called, and the focus is lost as is explained in many other StackOverflow answers. But renders after each click does not effect the focus in the second field. Why can't the same be true for the field using a styled-component?

import React, { useState } from "react"
import styled from "styled-components"
import "./styles.css"
function Form() {
  console.log("Form rendered")
  const [firstName, setFirstName] = useState("")
  const [lastName, setLastName] = useState("")

  const Input = styled.input`
    border: 2px solid blue;
    margin-right: 15px;
    width: 124px;
    font-weight: 800;
  `
  return (
    <form>
      <Input
        value={firstName}
        onChange={e => setFirstName(e.target.value)}
        placeholder="First name"
        type="text"
        name="firstName"
      />
      <input
        value={lastName}
        onChange={e => setLastName(e.target.value)}
        placeholder="Last name"
        type="text"
        name="lastName"
      />
    </form>
  );
}
export default Form

I ran this code in CodeSandbox, but that was my first time there (learning it) and I don't know how to make it available to others.

1
Could you provide us with the code that you're trying? I don't think this issue lies with styled-components per se.Webber
The symptom you describe most likely indicates that the component is being remounted with each key press. If you share the code involved, it will be possible to help further and figure out why. This is unlikely to be an issue with styled-components, but rather something wrong with how you are using it.Ryan Cogswell
This is probably the same problem as here: stackoverflow.com/questions/54846393/…Ryan Cogswell
I will try to make an example on CodeSandbox. I had some code there when I was trying to solve this, but lost it when I closed (my 1st time there).MartinDuo
I updated the question to include example code.MartinDuo

1 Answers

0
votes

Only React elements (instances of components) should be created on rendering; React components, including those built via styled-components, should be declared once, at the module scope or inside a high-order component function.

You're recreating the Input component at every time a Form is rendered, therefore the React's reconciliation algorithm unmounts the previous rendered <Input /> and remounts a new one. To fix it, move the declaration const Input = styled.input(...); to out of function Form(...) { ... }.