jen*_*nja 2 typescript reactjs react-hooks
我正在尝试学习 React 和 React Hooks。我创建了位于另一个文件中的自定义钩子:CustomHook.ts. 我在我的ContactForm.tsx. 我遇到的问题是内部的各个value={inputs.property}在<input />标签。Typescript 无法解析每个inputs._propertyName.
我已经定义了一个接口IContact来定义我想要使用的类型。我目前没有使用这个界面,因为我不知道把它放在哪里。
任何帮助将不胜感激!
错误:
ERROR in /jefthimi/src/components/Contact/ContactForm.tsx(35,31)
TS2339: Property 'subject' does not exist on type '{}'.
ERROR in /jefthimi/src/components/Contact/ContactForm.tsx(46,31)
TS2339: Property 'email' does not exist on type '{}'.
ERROR in /jefthimi/src/components/Contact/ContactForm.tsx(57,31)
TS2339: Property 'name' does not exist on type '{}'.
ERROR in /jefthimi/src/components/Contact/ContactForm.tsx(68,31)
TS2339: Property 'comments' does not exist on type '{}'.
Run Code Online (Sandbox Code Playgroud)
联系表格.tsx
import React from 'react';
import './ContactForm.scss';
import useContactForm from './CustomHook';
interface IContact {
subject: string;
email: string;
name: string;
comments: string;
}
const message = (inputs: any) => {
alert(`Message Sent!
Subject: ${inputs.subject}
Sender: ${inputs.email}
Name: ${inputs.name}
Comments: ${inputs.comments}`);
};
const { inputs, handleInputChange, handleSubmit } = useContactForm(message);
export default class ContactForm extends React.Component {
render() {
return (
<div className="contactForm_container">
<div className="contactForm_inner">
<form onSubmit={handleSubmit}>
<div className="input-group">
<label htmlFor="subject">Subject</label>
<input
id="subject"
name="subject"
type="text"
onChange={handleInputChange}
value={inputs.subject}
required
/>
</div>
<div className="input-group">
<label htmlFor="email">Your Email</label>
<input
id="email"
name="email"
type="text"
onChange={handleInputChange}
value={inputs.email}
required
/>
</div>
<div className="input-group">
<label htmlFor="name">Your Name</label>
<input
id="name"
name="name"
type="text"
onChange={handleInputChange}
value={inputs.name}
required
/>
</div>
<div className="input-group">
<label htmlFor="comments">Comments</label>
<textarea
name="comments"
id="comments"
rows={10}
onChange={handleInputChange}
value={inputs.comments}
required
/>
</div>
<div className="controls">
<button type="submit">Send Message</button>
</div>
</form>
</div>
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)
自定义钩子.ts
import React, { useState } from 'react';
/*
This is a Custom React Hook that handles our form submission
*/
const useContactForm = (callback) => {
const [inputs, setInputs] = useState({});
const handleSubmit = (event) => {
if (event) {
event.preventDefault();
}
callback();
};
const handleInputChange = (event) => {
event.persist();
setInputs((inputs) => ({
...inputs,
[event.target.name]: event.target.value
}));
};
return {
handleSubmit,
handleInputChange,
inputs
};
};
export default useContactForm;
Run Code Online (Sandbox Code Playgroud)
小智 7
问题是inputsCustomHook.ts中的初始状态是{}. 然后,你想渲染inputs.subject,inputs.email,inputs.name和inputs.comments。这些属性在空对象上不存在{},这是错误消息告诉您的。
让我们从一些基础知识开始。你有IContact,但你不知道如何处理它。您应该使用它在您期望该签名的任何位置键入数据。首先,message回调。
const message = (inputs: IContact) => {
alert(`Message Sent!
Subject: ${inputs.subject}
Sender: ${inputs.email}
Name: ${inputs.name}
Comments: ${inputs.comments}`);
};
Run Code Online (Sandbox Code Playgroud)
又如何useContactForm挂钩?嗯,你可以,但我不认为我会推荐它。当我看着那个钩子时,我没有看到它里面有任何引用IContact. 在这种情况下,钩子更通用。
如果只有某种方式可以添加更通用的打字...
嗯,有。我们想要做的是能够传入一个类型以用作其他对象的类型。
const useContactForm = <T>(callback: (state: T) => void) => {
//...code
}
Run Code Online (Sandbox Code Playgroud)
在这里,我<T>在箭头函数的前面添加了参数。我还输入了回调(value: T) => void以指示回调应该接受一种类型T作为参数并且不返回任何内容。
现在,我们需要键入useState函数。
const [inputs, setInputs] = useState<T>({});
Run Code Online (Sandbox Code Playgroud)
哦哦。{}不匹配T。我们需要一个类型为 的初始状态T。由于T正在传入,我们的初始状态也需要是。
const useContactForm = <T>(callback: (state: T) => void, initialState: T) => {
const [inputs, setInputs] = useState<T>(initialState);
// ...code
}
Run Code Online (Sandbox Code Playgroud)
并传进去。
const {inputs, handleInputChange, handleSubmit} = useContactForm(message, {
subject: '',
email: '',
name: '',
comments: '',
});
Run Code Online (Sandbox Code Playgroud)
好的。这基本上就是需要处理的方式。但是,TypeScript 和 Hooks 的代码和使用还存在其他几个问题。
ChangeEvent<HTMLInputElement | HTMLTextAreaElement>setInputs而不是新状态。callbackin handleSubmit,但message回调显然正在寻找IContact.这是一些工作代码。
联系表格.tsx
import React from 'react';
import './ContactForm.scss';
import useContactForm from './CustomHook';
interface IContact {
subject: string;
email: string;
name: string;
comments: string;
}
const message = (inputs: IContact) => {
alert(`Message Sent!
Subject: ${inputs.subject}
Sender: ${inputs.email}
Name: ${inputs.name}
Comments: ${inputs.comments}`);
};
export default () => {
const {inputs, handleInputChange, handleSubmit} = useContactForm(message, {
subject: '',
email: '',
name: '',
comments: '',
});
return (
<div className="contactForm_container">
<div className="contactForm_inner">
<form onSubmit={handleSubmit}>
<div className="input-group">
<label htmlFor="subject">Subject</label>
<input
id="subject"
name="subject"
type="text"
onChange={handleInputChange}
value={inputs.subject}
required
/>
</div>
<div className="input-group">
<label htmlFor="email">Your Email</label>
<input
id="email"
name="email"
type="text"
onChange={handleInputChange}
value={inputs.email}
required
/>
</div>
<div className="input-group">
<label htmlFor="name">Your Name</label>
<input
id="name"
name="name"
type="text"
onChange={handleInputChange}
value={inputs.name}
required
/>
</div>
<div className="input-group">
<label htmlFor="comments">Comments</label>
<textarea
name="comments"
id="comments"
rows={10}
onChange={handleInputChange}
value={inputs.comments}
required
/>
</div>
<div className="controls">
<button type="submit">Send Message</button>
</div>
</form>
</div>
</div>
);
};
Run Code Online (Sandbox Code Playgroud)
自定义钩子.ts
import React, {useState, FormEvent, ChangeEvent} from 'react';
/*
This is a Custom React Hook that handles our form submission
*/
const useContactForm = <T>(callback: (state: T) => void, initialState: T) => {
const [inputs, setInputs] = useState<T>(initialState);
const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
if (event) {
event.preventDefault();
}
callback(inputs);
};
const handleInputChange = (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
event.persist();
setInputs({
...inputs,
[event.target.name]: event.target.value,
});
};
return {
handleSubmit,
handleInputChange,
inputs,
};
};
export default useContactForm;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5491 次 |
| 最近记录: |