我什么时候应该调用自定义钩子而不违反任何钩子规则?

时间:2021-04-24 21:28:37

标签: javascript reactjs react-hooks use-effect

我确实有一个带有表单的简单组件。我想使用 useSendEmail 钩子返回服务器响应(成功或失败)。我在哪里调用这个钩子,这样它就不会在第一次渲染时触发,而是在我从用户那里获取数据并将其保存在状态后才触发?

预期行为:当电子邮件对象包含用户输入并返回状态(如果发送成功与否)时,将调用钩子 useSendEmail。

我知道我需要在组件的顶层调用钩子,但我是否在等待来自输入字段的数据?

实际行为:我违反了钩子规则。

class CustomSignupForm(SignupForm):
    first_name = forms.CharField(required=True,label='First Name')
    last_name = forms.CharField(required=True,label='Last Name')
    image = forms.ImageField(required=True,label='your photo')
    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.image = self.cleaned_data['image']
        user.save()
        return user

编辑: 这就是我的钩子在用你的建议重构后的样子。我现在正在顶级组件中导入钩子和方法,一切似乎都运行良好。

// importing everything I need here
const ContactPage = () => {
    const initial = {
        from: '',
        message: '',
        email: '',
    };
    const [formData, setFormData] = useState(initial);
    const [email, setEmail] = useState(null);

    const handleChange = ({ name, value }) => {
        setFormData({ ...formData, [name]: value });
    };
    
    useEffect(() => {
        if (email === null) return;
        const response = useSendEmail(email);       
    }, [email]);

    const handleSubmit = (e) => {
        e.preventDefault();
        setEmail(formData);
    };

    return (
        <DefaultLayout title="Contact">
            <StyledContainer>
                <form className="contact_form" onSubmit={(e) => handleSubmit(e)}>
                    <input
                        name="from"
                        type="text"
                        value={formData.from}
                        onChange={(e) => handleChange(e.target)}
                        placeholder="Your full name"
                    />
                    <textarea
                        name="message"
                        value={formData.message}
                        onChange={(e) => handleChange(e.target)}
                        placeholder="Your Message"
                    />
                    <input
                        name="email"
                        type="email"
                        value={formData.email}
                        onChange={(e) => handleChange(e.target)}
                        placeholder="Your e-mail"
                    />
                    <button type="submit">SUBMIT</button>
                </form>
            </StyledContainer>
        </DefaultLayout>
    );
};

export default ContactPage;

0 个答案:

没有答案