【问题标题】:How to make redux-form work with TypeScript and styled-components?如何使 redux-form 与 TypeScript 和 styled-components 一起使用?
【发布时间】:2018-03-18 03:25:23
【问题描述】:

我正在尝试让 redux-form 与 TypeScript 和 styled-components 一起使用。在下面的代码示例中,为什么它不适用于样式化输入组件?输入呈现,但每次按键都失去焦点。还需要单击两次才能聚焦元素。似乎 redux-form 试图控制从 styled-components 返回的包装元素? redux-form 和 styled-components 都使用 HOC - 高阶组件将 props 传递给底层元素。

export interface ITxtProps extends WrappedFieldProps {
  label?: string;
}

export const FieldHack = class extends Field<any> {};

const renderTxt = (props: ITxtProps & GenericFieldHTMLAttributes) => {
  const StyledInput = styled.input`
    background-color: deeppink;
  `;
  const notWorking = <StyledInput {...props.input} />;
  const worksPerfectly = <input {...props.input} />;
  return (
  <div>
    <div>{props.label}</div>
    {notWorking}
  </div>
);
}

const NormalLoginComponent = (props: {
  handleSubmit?: SubmitHandler<{}, {}>;
}) => {
  const { handleSubmit } = props;
  return (
    <form onSubmit={handleSubmit}>
      {/* this does not work when using styled components: */}
      <Field name={'email'} component={renderTxt}  />

      {/* this gives an error, property label does not exist on type... */}
      {/*<Field name={'email'} component={renderTxt} label="email" />*/}

      {/* this works, but no intellisense/static types */}
      <FieldHack name={'email2'} component={renderTxt} label="email" />

      <Field name={'password'} component={'input'} type="password" />
      <Button text={'log in'} onClick={handleSubmit} />
    </form>
  );
};

export interface ILoginForm {
  email: string;
  password: string;
}

const LoginForm = reduxForm<Readonly<ILoginForm>, {}>({
  form: 'loginNormal',
})(NormalLoginComponent);

【问题讨论】:

  • 我也有同样的问题。 @Tomas 你有什么结果吗?

标签: typescript redux-form styled-components


【解决方案1】:

是的,我终于想通了。我犯了一个错误,那就是在 render 方法中创建了我的 styled-component 包装器:

const StyledInput = styled.input`
  background-color: deeppink;
;

显然在 render() 中应用 HOC - 高阶组件是不安全的。因此,将 HOC 移到渲染之外时它应该可以工作:

export interface ITxtProps extends WrappedFieldProps {
  label?: string;
}

export const FieldHack = class extends Field<any> {};

// wrap you HOC outside render:
const StyledInput = styled.input`
    background-color: deeppink;
  `;

const renderTxt = (props: ITxtProps & GenericFieldHTMLAttributes) => {
  // works now :)
  const notWorking = <StyledInput {...props.input} />;
  const worksPerfectly = <input {...props.input} />;
  return (
  <div>
    <div>{props.label}</div>
    {notWorking}
  </div>
);
}

当我弄清楚这一点时,我正在阅读另一个 HOC 库上的文档,这里有一个链接解释了在哪里可以安全地应用(任何)HOC:redux-auth-wrapper documentation on HOCs

【讨论】:

  • 嘿,我想知道为什么 FieldHack 首先需要存在。我在我的项目中遇到了同样的问题,但无法绕过这一步。你有没有找到更好的解决方案来在 typescript 中为 redux-form 创建自定义组件?
  • FieldHack 只是一个帮手,因为您不能在渲染/TSX 中使用给定类型的泛型(TypeScript 泛型与反应标记冲突?)我认为 redux-forms 与普通 JavaScript 一起工作得更好。或者也许我只是不知道如何在 TypeScript 中做到这一点:)
  • 啊,好的,感谢您的澄清。 :) 我在使用 redux-form 和 TypeScript 时也遇到了很多麻烦,定义有点复杂。没有多少完整的例子可供参考。
猜你喜欢
  • 2022-07-29
  • 2020-02-16
  • 2022-08-18
  • 1970-01-01
  • 2018-04-15
  • 2020-10-07
  • 2019-07-11
  • 2020-03-02
  • 2021-05-30
相关资源
最近更新 更多