我正在使用样式化的组件。我必须使用它来更改样式,因为我需要更改的内容嵌套在 Kendo React Grid 中,正如他们在文档中概述的那样:https://www.telerik.com/kendo-react-ui/components/styling/styled-components/
我需要根据道具动态设置组件样式。由此产生的问题是,由于每个呈现周期都会创建一个新组件,因此文本输入会在您键入时失去焦点。我试图将组件包装在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."
顶部文本框在更新时失去焦点。下部记忆的那个命中钩子错误。
解决这个问题的更好模式是什么?
正如Matt Carlotta在他的评论中指出的那样,我通过在功能组件中定义样式组件来使用反模式。我认为有必要在道具在范围内定义它,以便使用道具进行造型。我在样式组件中错过的是,您可以将样式定义为 props 的函数,并且它将按预期运行。我用正确的实现更新了示例。
stackblitz.com/edit/react-mu6rlr-omeo5c?file=app%2Fmain.jsx