事件触发样式组件 css 更改
Event triggered styled component css change
我现在才切换到样式化组件,找不到这个相当简单的逻辑的答案:如果字段验证失败,它应该有红色边框。
带有 classic CSS classes:
const validateMail = (e) => {
let mail = e.target.value;
if (!mailRegex.test(mail)) {
e.target.classList.add("error");
return;
}
e.target.classList.remove("error");
}
我怎样才能做类似于e.target.classList.add("error")
的事情?我假设我必须以某种方式将此列表更改为可以更改字段样式的内容。这是触发此功能的输入样式组件的完整 class:
const Field = styled.div`
display: flex;
flex-direction: column;
`;
const Label = styled.label`
font: ${fonts.body1};
font-size: .75rem;
`;
const Input = styled.input`
font: ${fonts.body1};
padding: 10px;
border-radius: 5px;
outline: none;
border: 1px solid rgba(0, 0, 0, 0.3);
width: 100%;
resize: none;
box-sizing: border-box;
&:focus {
border: 1px solid ${palette.primary_blue};
}
`;
function InputField(props) {
return (
<Field>
<Label htmlFor={"txt" + props.name}>{props.name + ":"}</Label>
<Input name={"txt" + props.name} onKeyUp={props.onKeyUp}></Input>
</Field>
);
}
export default InputField;
如您所见,带样式的组件不遵循 classic class 列表范例。有几种方法可以达到您想要的结果。我已经演示了 2.
方法 1:将 prop 传递给样式化组件。
您可以像这样将自定义 isValid
道具传递给样式化组件:
<Input
isValid={isValid}
name={"txt" + props.name}
onKeyUp={props.onKeyUp}
/>
然后您可以根据 prop 的评估方式在样式化组件中添加条件渲染逻辑。
请注意,样式化组件定义中的以下箭头函数(代替 styled.input
)可确保将 prop 视为组件 prop 而不是实际的 DOM 元素属性(这将不是有效标记并可能导致错误):
const Input = styled(({
isValid,
...props
}) => <input {...props} />)`
border: 1px solid ${({ isValid }) =>
isValid ? `rgba(0, 0, 0, 0.3)` : `red`)};
/* ... the rest of your styles... */
`;
有关上述内容的实例,请参阅此 Code Sandbox。请注意第 41 行,其中 isValid
被设置为 false
作为实际验证逻辑的替代。尝试将其更改为 true
,您会看到边框颜色发生变化。
方法 2:为有效状态和错误状态创建 2 个独立样式的组件:
const Input = styled.input`
border: 1px solid rgba(0, 0, 0, 0.3);
/* ... the rest of your styles... */
`;
const ErrorInput = styled(Input)`
border-color: red;
`;
const StyledInput = isValid ? Input : ErrorInput;
return (
<Field>
<Label htmlFor={"txt" + props.name}>{props.name + ":"}</Label>
<StyledInput
name={"txt" + props.name}
onKeyUp={props.onKeyUp}
/>
</Field>
);
这是此方法的 Code Sandbox。与第一种方法相同,请参阅第 45 行以了解硬编码 isValid
值。
关于转换的注意事项
我更喜欢第一个解决方案,因为它允许在变化的值之间平滑过渡(就像 classes)。第二种方法适用于静态渲染元素,但当组件引用从 Input
更改为 ErrorInput
时,它基本上会 destroy/create 动态生成一个新元素。如果你想要平滑过渡,那么你应该使用第一种方法。
我现在才切换到样式化组件,找不到这个相当简单的逻辑的答案:如果字段验证失败,它应该有红色边框。
带有 classic CSS classes:
const validateMail = (e) => {
let mail = e.target.value;
if (!mailRegex.test(mail)) {
e.target.classList.add("error");
return;
}
e.target.classList.remove("error");
}
我怎样才能做类似于e.target.classList.add("error")
的事情?我假设我必须以某种方式将此列表更改为可以更改字段样式的内容。这是触发此功能的输入样式组件的完整 class:
const Field = styled.div`
display: flex;
flex-direction: column;
`;
const Label = styled.label`
font: ${fonts.body1};
font-size: .75rem;
`;
const Input = styled.input`
font: ${fonts.body1};
padding: 10px;
border-radius: 5px;
outline: none;
border: 1px solid rgba(0, 0, 0, 0.3);
width: 100%;
resize: none;
box-sizing: border-box;
&:focus {
border: 1px solid ${palette.primary_blue};
}
`;
function InputField(props) {
return (
<Field>
<Label htmlFor={"txt" + props.name}>{props.name + ":"}</Label>
<Input name={"txt" + props.name} onKeyUp={props.onKeyUp}></Input>
</Field>
);
}
export default InputField;
如您所见,带样式的组件不遵循 classic class 列表范例。有几种方法可以达到您想要的结果。我已经演示了 2.
方法 1:将 prop 传递给样式化组件。
您可以像这样将自定义 isValid
道具传递给样式化组件:
<Input
isValid={isValid}
name={"txt" + props.name}
onKeyUp={props.onKeyUp}
/>
然后您可以根据 prop 的评估方式在样式化组件中添加条件渲染逻辑。
请注意,样式化组件定义中的以下箭头函数(代替 styled.input
)可确保将 prop 视为组件 prop 而不是实际的 DOM 元素属性(这将不是有效标记并可能导致错误):
const Input = styled(({
isValid,
...props
}) => <input {...props} />)`
border: 1px solid ${({ isValid }) =>
isValid ? `rgba(0, 0, 0, 0.3)` : `red`)};
/* ... the rest of your styles... */
`;
有关上述内容的实例,请参阅此 Code Sandbox。请注意第 41 行,其中 isValid
被设置为 false
作为实际验证逻辑的替代。尝试将其更改为 true
,您会看到边框颜色发生变化。
方法 2:为有效状态和错误状态创建 2 个独立样式的组件:
const Input = styled.input`
border: 1px solid rgba(0, 0, 0, 0.3);
/* ... the rest of your styles... */
`;
const ErrorInput = styled(Input)`
border-color: red;
`;
const StyledInput = isValid ? Input : ErrorInput;
return (
<Field>
<Label htmlFor={"txt" + props.name}>{props.name + ":"}</Label>
<StyledInput
name={"txt" + props.name}
onKeyUp={props.onKeyUp}
/>
</Field>
);
这是此方法的 Code Sandbox。与第一种方法相同,请参阅第 45 行以了解硬编码 isValid
值。
关于转换的注意事项
我更喜欢第一个解决方案,因为它允许在变化的值之间平滑过渡(就像 classes)。第二种方法适用于静态渲染元素,但当组件引用从 Input
更改为 ErrorInput
时,它基本上会 destroy/create 动态生成一个新元素。如果你想要平滑过渡,那么你应该使用第一种方法。