【问题标题】:How to implement an props interface for conditions with styled components in React with Typescript如何在 React with Typescript 中为带有样式组件的条件实现 props 接口
【发布时间】:2021-08-10 13:16:59
【问题描述】:

这是一个用 React 编写的组件,带有处理用户输入的库“样式化组件”。如果用户的输入无效,则应显示如下所示的相应样式(类无效)。该示例与 JavaScript 完美配合。但是,使用 TypeScript,我无法让 props 界面正常工作。作为一种解决方法,我为styled.div<any> 插入了<any>,这解决了错误,但当然也违背了TypeScript 的目的。错误输出显示在代码后面。

import { useState } from "react";
import styled from 'styled-components';
import Button from "../../UI/Button/Button";

const FormControl = styled.div<any>`
&.invalid label {
  color: red
}
&.invalid input {
  border-color: red;
  background: salmon;
}
`;

interface onAddGoalProps {
  onAddGoal: (enteredValue: string) => void;
}

const CourseInput: React.FC<onAddGoalProps> = ({ onAddGoal }) => {
  const [enteredValue, setEnteredValue] = useState("");
  const [isValid, setIsValid] = useState(true);

  const goalInputChangeHandler = (event: any) => {
    if (event.target.value.trim().length > 0) {
      setIsValid(true);
    }
    setEnteredValue(event.target.value);
  };

  const formSubmitHandler = (event: any) => {
    event.preventDefault();
    if (enteredValue.trim().length === 0) {
      setIsValid(false);
      return;
    }
    onAddGoal(enteredValue);
    setEnteredValue("");
    setIsValid(true);
  };

  return (
    <form onSubmit={formSubmitHandler}>
      <FormControl className={isValid && 'invalid'}>
        <label>Course Goal</label>
        <input
          type="text"
          onChange={goalInputChangeHandler}
          value={enteredValue}
        />
      </FormControl>
      <Button type="submit">Add Goal</Button>
    </form>
  );
};

export default CourseInput;

这里是错误输出:

C:/Users/stroebele/dev/training/repositories/React-Library/3_advanced/app_tasks-manager/src/components/CourseGoals/CourseInput/CourseInput.tsx
  TypeScript error in C:/Users/stroebele/dev/training/repositories/React-Library/3_advanced/app_tasks-manager/src/components/CourseGoals/CourseInput/CourseInput.tsx(72,20):
  No overload matches this call.
    Overload 1 of 2, '(props: Omit<Omit<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<...>> & { ...; }, never> & Partial<...>, "theme"> & { ...; } & { ...; }): ReactElement<...>', gave the following error.        
      Type 'false | "invalid"' is not assignable to type 'string | undefined'.
        Type 'false' is not assignable to type 'string | undefined'.
    Overload 2 of 2, '(props: StyledComponentPropsWithAs<"div", any, {}, never, "div">): ReactElement<StyledComponentPropsWithAs<"div", any, {}, never, "div">, string | JSXElementConstructor<...>>', gave the following error.
      Type 'false | "invalid"' is not assignable to type 'string | undefined'.  TS2769
  
      70 |       {/* because the styles are already attached via "styles components" */}
      71 |       {/* The case for " */}
    > 72 |       <FormControl className={isValid && 'invalid'}>
         |                    ^
      73 |         <label>Course Goal</label>
      74 |         <input
      75 |           type="text"

【问题讨论】:

    标签: reactjs typescript styled-components


    【解决方案1】:

    您应该在 `${}` 中使用此条件

    <FormControl className={`${!isValid && 'invalid'}`}>
    

    这里的问题是,当isValid 为真时,会在 HTML 中编译一个字符串 'false',如下所示:

    <div class='false'>
    

    解决方法是这样设置类名:

    <FormControl className={`${(!isValid && "invalid") || ""}`}>
    

    另一种解决方案是使用三元条件:

    className={isValid ? '' : "invalid"}
    

    【讨论】:

      【解决方案2】:

      试试看。传递道具、声明类型和有条件的样式。

       const FormControl = styled.div<{invalid?: boolean}>`
        ${p => p.invalid && `
          input {
            border-color: red;
            background: salmon;
          }
      
          label {
            color: red
          }
        `}
      `;
      
       <FormControl invalid={!isValid}>children</FormControl>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-04
        • 2022-01-15
        • 2018-07-01
        • 1970-01-01
        • 2020-07-28
        • 2020-11-05
        • 1970-01-01
        • 2023-03-05
        相关资源
        最近更新 更多