{"id":463,"date":"2026-06-18T09:49:01","date_gmt":"2026-06-18T01:49:01","guid":{"rendered":"https:\/\/mitongxue.cn\/?p=463"},"modified":"2026-06-18T09:49:01","modified_gmt":"2026-06-18T01:49:01","slug":"react%e5%bf%98%e8%ae%b0%e5%af%86%e7%a0%81%e5%8a%9f%e8%83%bd%e5%ae%9e%e7%8e%b0","status":"publish","type":"post","link":"https:\/\/mitongxue.cn\/index.php\/2026\/06\/18\/react%e5%bf%98%e8%ae%b0%e5%af%86%e7%a0%81%e5%8a%9f%e8%83%bd%e5%ae%9e%e7%8e%b0\/","title":{"rendered":"React\u5fd8\u8bb0\u5bc6\u7801\u529f\u80fd\u5b9e\u73b0"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">forgetPwd.jsx<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>import React, { useState } from 'react';\nimport SmCodeLogin from '.\/component\/SmCodeLogin.jsx'\nimport { Form, Input, Button, Row, message } from 'antd';\nimport UpdatePassword from '.\/component\/UpdatePassword.jsx';\nimport '.\/css\/login.less';\nimport $http from 'api';\nimport { useSelector, history  } from 'umi';\n\nconst FormItem = Form.Item;\nconst ForgetPwd = () => {\n    const &#91;form] = Form.useForm();\n    const &#91;step, setStep] = useState(1);\n    \/\/console.log(form,'form');\n    const submitSelect = (data) => {\n       step === 1 ? checkCode(data) : updatePassword(data.confirmPassword);\n    }\n\n    const checkCode = async (params) => { \n        \/\/console.log(\"params\",params.code);\n        const {data,msg} = await $http.checkedCode({smCode:params.code});\n        \/\/ if(data.code === 0){\n        \/\/     setStep(2);\n        \/\/ }else{\n        \/\/     message.error(msg);\n        \/\/ }\n        console.log(\"checkCode\",code,data,msg);\n        if(data){\n            setStep(2);\n        }else{\n            message.error(msg);\n        }\n    }\n    const updatePassword = async (newPassword) => { \n        console.log(\"updatePassword\",newPassword);\n        const {data,msg} = await $http.resetPassword({newPassword});\n        if(data){\n            message.success('\u5bc6\u7801\u91cd\u7f6e\u6210\u529f');\n            history.replace('\/users\/login');\n        }else{\n            message.error(msg);\n        }\n    }\n    const ComponentSelector = (props) => step === 1 ? &lt;SmCodeLogin {...props} \/> : &lt;UpdatePassword {...props} \/>;\n\n    return (\n        &lt;div className=\"form-wrapper forget-pwd\">\n            &lt;div className=\"forget-password-title\">\n                {step === 1 ? '\u5fd8\u8bb0\u5bc6\u7801' : '\u91cd\u7f6e\u5bc6\u7801'}\n            &lt;\/div>\n            &lt;Form form={form} onFinish={submitSelect}>\n                {ComponentSelector({form, FormItem, Input, Button})}\n                &lt;Row>\n                    &lt;Button \n                    block={true} \n                    type=\"primary\" \n                    htmlType=\"submit\"\n                    >{step===1 ? '\u4e0b\u4e00\u6b65':'\u91cd\u7f6e\u5bc6\u7801'}&lt;\/Button>\n                &lt;\/Row>\n            &lt;\/Form>\n        &lt;\/div>\n    );\n};\n\n\nexport default ForgetPwd;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">user\/component\/SmcodeLogin.jsx<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u53d1\u9001\u9a8c\u8bc1\u7801\u7ec4\u4ef6<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React from 'react';\nimport IconMap from 'components\/IconMap.jsx';\nimport { LoginRule } from 'utils\/rules';\nimport { Space } from 'antd';\nconst { Compact } = Space;\nimport { useState, useRef, useEffect, useDispatch } from 'react';\nimport $http from 'api';\nimport { message } from 'antd';\n\nconst SmCodeLogin = ({form, FormItem, Input, Button}) => {\n    \/\/const dispatch = useDispatch();\n    const handleSendCode = async () => {\n        \/\/console.log('\u53d1\u9001\u9a8c\u8bc1\u7801');\n        setCodeStatus(false);\n        const mobile = form.getFieldValue('mobile');\n        console.log(mobile,'mobile');\n        const res  = await $http.getSmsCode({mobile});\n        console.log(res,'res');\n        message.success(res.msg);\n        setDisabled(true);\n        runTime();\n    }\n    const &#91;disabled, setDisabled] = useState(true);\n    const &#91;leftTime, setLeftTime] = useState(60);\n    const &#91;codeStatus, setCodeStatus] = useState(true);\n      const timerRef = useRef(null);\n    const runTime = () => { \n        \/\/ \u9632\u6b62\u91cd\u590d\u70b9\u51fb\u591a\u6b21\u5f00\u542f\u5b9a\u65f6\u5668\n        if (timerRef.current) return;\n        setCodeStatus(false);\n        timerRef.current = setInterval(()=>{\n            setLeftTime(prev=>{\n                if(prev &lt;= 1){\n                    clearInterval(timerRef.current);\n                    timerRef.current = null;\n                    setCodeStatus(true);\n                    setDisabled(false);\n                    return 60;\n                }   \n                return prev-1;\n            });\n        },1000)\n    }\n\n    \/\/ \u7ec4\u4ef6\u5378\u8f7d\u5f3a\u5236\u6e05\u5b9a\u65f6\u5668\n    useEffect(() => {\n        return () => {\n            if (timerRef.current) clearInterval(timerRef.current);\n        };\n    }, &#91;]);\n    const checkMobile = async (e) => {\n        console.log(e.target.value,'e.target.value');\n        \/\/const status = await form.validateFields(&#91;'mobile']);\n        \/\/\u56e0\u4e3a\u8fd4\u56de\u7684promise2\u79cd\u72b6\u6001\u91c7\u7528trycatch\u5904\u7406\n        try{\n            const data = await form.validateFields(&#91;'mobile']);\n            console.log(data,'data');\n            setDisabled(false);\n        }catch(error){\n            console.log(error,'error');\n            setDisabled(true);\n        }\n    }\n    return (\n        &lt;>\n            &lt;FormItem\n                name=\"mobile\"\n                rules={LoginRule.mobileRule}\n                hasFeedback={true}\n            >\n                &lt;Input  onChange={checkMobile} prefix={IconMap.mobile} placeholder=\"\u8bf7\u8f93\u5165\u624b\u673a\u53f7\" \/>\n            &lt;\/FormItem>\n            &lt;FormItem\n                name=\"code\"\n                rules={LoginRule.codeRule}\n                hasFeedback={true}\n            >\n                &lt;Compact>\n                    &lt;Input   \n                    prefix={IconMap.code} \n                    placeholder=\"\u8bf7\u8f93\u5165\u9a8c\u8bc1\u7801\"\n                    \/\/ addonAfter={&lt;Button onClick={handleSendCode}>\u53d1\u9001\u9a8c\u8bc1\u7801&lt;\/Button>} \n                    \/>\n                    &lt;Button \n                        disabled={disabled} \n                        onClick={handleSendCode}\n                    >\n                        {codeStatus ? '\u53d1\u9001\u9a8c\u8bc1\u7801' : `${leftTime}\u79d2\u540e\u91cd\u65b0\u53d1\u9001`}\n                        \n                    &lt;\/Button>\n                &lt;\/Compact>\n            &lt;\/FormItem>\n        &lt;\/>\n    );\n}\n\nexport default SmCodeLogin;\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">src\\pages\\users\\component\\UpdatePassword.jsx<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u7b2c\u4e8c\u6b65\u91cd\u7f6e\u5bc6\u7801\u7ec4\u4ef6<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React from 'react';\nimport IconMap from 'components\/IconMap.jsx';\nimport { LoginRule } from 'utils\/rules';\nconst UpdatePassword = ({form, FormItem, Input}) => {\n    return (\n        &lt;>\n        &lt;FormItem\n            name=\"newPassword\"\n            rules={LoginRule.passwordRule}\n            hasFeedback={true}\n        >\n            &lt;Input    type=\"password\" prefix={IconMap.lock} placeholder=\"\u65b0\u5bc6\u7801\" \/>\n        &lt;\/FormItem>\n        &lt;FormItem\n            name=\"confirmPassword\"\n            rules={LoginRule.confirmPasswordRule(form)}\n            hasFeedback={true}\n        >\n            &lt;Input type=\"password\" prefix={IconMap.lock} placeholder=\"\u786e\u8ba4\u65b0\u5bc6\u7801\" \/>\n        &lt;\/FormItem>\n        &lt;\/>\n    );\n}\n\nexport default UpdatePassword;\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">src\\servicer\\interface\\user.js<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">api\u63a5\u53e3<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import ajax from '..\/http';\n\nexport const userLogin = (params) => ajax.post('\/api\/login', params);\n\n\/\/\u624b\u673a\u9a8c\u8bc1\u7801\nexport const getSmsCode = (params) => ajax.get('\/api\/getCode', params);\nexport const checkedCode = (params) => ajax.get('\/api\/checkSmCode', params);\n\nexport const resetPassword = (params) => ajax.post('\/api\/resetPassword', params);\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\u89c4\u5219\u6821\u9a8c<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>export const LoginRule = {\n  userRule :&#91;\n    { required: true, message: '\u8bf7\u8f93\u5165\u7528\u6237\u540d' },\n    { max: 16, message: '\u7528\u6237\u540d\u957f\u5ea6\u4e0d\u5408\u6cd5'},\n    { min: 4, message: '\u7528\u6237\u540d\u957f\u5ea6\u4e0d\u5408\u6cd5'},\n  ],\n  passwordRule :&#91;\n    { required: true, message: '\u8bf7\u8f93\u5165\u5bc6\u7801' },\n    { max: 32, message: '\u5bc6\u7801\u957f\u5ea6\u4e0d\u5408\u6cd5'},\n    { min: 4, message: '\u5bc6\u7801\u957f\u5ea6\u4e0d\u5408\u6cd5'},\n  ],\n  mobileRule :&#91;\n    \/\/ { required: true, message: '\u8bf7\u8f93\u5165\u624b\u673a\u53f7' },\n    \/\/ { pattern: \/^1&#91;3456789]\\d{9}$\/, message: '\u624b\u673a\u53f7\u683c\u5f0f\u9519\u8bef'},\n    {\n      validator: (rule, value, callback) => {\n        const mobileReg = \/^1&#91;3|4|5|6|7|8]&#91;0-9]\\d{8}$\/;\n        switch (true) {\n          case !Boolean(value):\n            return Promise.reject('\u624b\u673a\u53f7\u4e0d\u80fd\u4e3a\u7a7a');\n          case !mobileReg.test(value):\n            return Promise.reject('\u624b\u673a\u53f7\u683c\u5f0f\u9519\u8bef');\n          default:\n            return Promise.resolve();\n        }\n      }\n    }\n  ],\n  codeRule :&#91;\n    { required: true, message: '\u8bf7\u8f93\u5165\u9a8c\u8bc1\u7801' },\n    { len: 6, message: '\u9a8c\u8bc1\u7801\u957f\u5ea6\u9519\u8bef'},\n  ],\n  confirmPasswordRule:(form)=>{\n    return &#91;\n      {\n        validator: (rule, value, callback) => {\n          switch (true) {\n            case !Boolean(value):\n              return Promise.reject('\u8bf7\u8f93\u5165\u786e\u8ba4\u5bc6\u7801');\n            case value !== form.getFieldValue('newPassword'):\n                return Promise.reject('\u4e24\u6b21\u8f93\u5165\u7684\u5bc6\u7801\u4e0d\u4e00\u81f4');\n            default:\n              return Promise.resolve();\n          }\n        }\n      }\n    ]\n  }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>forgetPwd.jsx user\/compon..<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,11],"tags":[],"class_list":["post-463","post","type-post","status-publish","format-standard","hentry","category-react-","category-front"],"featured_image_urls":{"full":"","thumbnail":"","medium":"","medium_large":"","large":"","1536x1536":"","2048x2048":""},"author_info":{"info":["\u9648 \u67d0\u4eba"]},"category_info":"<a href=\"https:\/\/mitongxue.cn\/index.php\/category\/front\/react-%e5%89%8d%e7%ab%af\/\" rel=\"category tag\">React<\/a> <a href=\"https:\/\/mitongxue.cn\/index.php\/category\/front\/\" rel=\"category tag\">\u524d\u7aef<\/a>","tag_info":"\u524d\u7aef","comment_count":"0","_links":{"self":[{"href":"https:\/\/mitongxue.cn\/index.php\/wp-json\/wp\/v2\/posts\/463","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mitongxue.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mitongxue.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mitongxue.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mitongxue.cn\/index.php\/wp-json\/wp\/v2\/comments?post=463"}],"version-history":[{"count":2,"href":"https:\/\/mitongxue.cn\/index.php\/wp-json\/wp\/v2\/posts\/463\/revisions"}],"predecessor-version":[{"id":465,"href":"https:\/\/mitongxue.cn\/index.php\/wp-json\/wp\/v2\/posts\/463\/revisions\/465"}],"wp:attachment":[{"href":"https:\/\/mitongxue.cn\/index.php\/wp-json\/wp\/v2\/media?parent=463"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mitongxue.cn\/index.php\/wp-json\/wp\/v2\/categories?post=463"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mitongxue.cn\/index.php\/wp-json\/wp\/v2\/tags?post=463"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}