2

我正在使用样式组件。我必须使用它来更改样式,因为我需要更改的内容嵌套在 Kendo React Grid 中,正如他们在文档中概述的那样:https ://www.telerik.com/kendo-react-ui/components/styling/样式化组件/

我需要根据道具动态设置组件样式。这造成的问题是,由于每个渲染周期都会创建一个新组件,因此文本输入会在您键入时失去焦点。我试图将组件包装在 useMemo 中来解决这个问题,但它会导致“渲染的钩子比预期的少”错误。似乎 useRef 是从 styled-components 在 styled() 中调用的,因此当它随后由于 useMemo 被跳过时,它会创建挂钩不匹配。

我在这里创建了一个更简单的示例:https ://stackblitz.com/edit/react-mu6rlr-omeo5c?file=app%2Fmain.jsx

function CustomText(props){
  const [state, setState] = useState('text')
  const {color} = props

  const Input = styled('input')`
    background-color: ${color}
  `

  return <Input value={state} onChange={useCallback(event => setState(event.target.value))}/>
}
// loses focus on update


function CustomTextMemo(props){
  const [state, setState] = useState('memoized')
  const {color} = props

  const Input = useMemo(
    () => styled('input')`
      background-color: ${color}
    `,
    [color]
  )

  return <Input value={state} onChange={useCallback(event => setState(event.target.value))}/>
}
// "Rendered fewer hooks than expected. This may be caused by an accidental early return statement."

顶部的文本框失去了对更新的关注。较低的记忆中的一个命中钩子错误。

解决这个问题的更好模式是什么?

4

1 回答 1

1

正如 Matt Carlotta 在他的评论中指出的那样,我通过在功能组件中定义样式组件来使用反模式。我认为有必要在 props 的范围内定义它,以便使用 props 进行样式设置。我在 styled-components 中错过的是您可以将样式定义为 props 的函数,并且它将按预期运行。我用正确的实现更新了这个例子。

stackblitz.com/edit/react-mu6rlr-omeo5c?file=app%2Fmain.jsx

于 2020-06-08T18:12:01.593 回答