Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.4k views
in Technique[技术] by (71.8m points)

React更新state怎样才能避免更新整个组件?

刚入门REACT,不懂react渲染逻辑。
为什么输入框输入内容的时候会重新渲染子组件?比如渲染NameAndPhone组件,在用户名输入框输入内容的时候,NameAndPhone组件会全部刷新(浏览器表现为整个NameAndPhone组件节点全部更新),导致输入一个字母,输入框就会失去焦点。

import React, { useState, useEffect } from 'react';

import './login.scss'

function Login() {
  const [fullname, setFullname] = useState('')
  const [idCard, setIdCard] = useState('')
  const [tel, setTel] = useState('')
  const [code, setCode] = useState('')
  const [tab, setTab] = useState('phone')
  const [codeText, setCodeText] = useState('获取验证码')

  useEffect(() => {
    console.log('update')
  });

  // let LoginForm;
  // if (tab === 'phone') {
  //   LoginForm = <NameAndPhone />
  // } else {
  //   LoginForm = <NameAndIdcard />
  // }

  return (
    <div className="login-page">
      <img src="./sc-report-login-top.jpg" alt="re" className="top-bg-img" />
      <div className="tab-l" id="change-btn">
        <div className={`item ${tab==="phone"?"active":""}`} op="phone" onClick={() => setTab("phone")}>使用手机号查询</div>
        <div className={`item ${tab==="idcard"?"active":""}`} op="idcard" onClick={() => setTab("idcard")}>使用身份证号查询</div>
      </div>
      {tab==='phone'? <NameAndPhone /> : <NameAndIdcard />}
    </div>
  )

  function NameAndPhone() {
    return (
      <div className="login-form">
        <label className="login-form-item" htmlFor="fullname">
          <img src="./sc-login-page-user-v2.png" className="login-icon" alt="login-user.png" />
          <input id="fullname" type="text" placeholder="请输入姓名" className="login-text" maxLength="16" value={fullname} onChange={(ev) => setFullname(ev.target.value)}/>
        </label>
        <label className="login-form-item m-t-30 type1" htmlFor="tel">
          <img src="./entry-bg-account-v2.png" className="login-icon" alt="entry-bg-account-v2.png" />
          <input id="tel" type="text" placeholder="请输入联系方式" className="login-text" maxLength="16" value={tel} onChange={(ev) => setTel(ev.target.value)}/>
        </label>
        <div className="code-wrapper m-t-30 m-b-60 type1">
          <label className="login-form-item m-r-30">
            <img src="./entry--bg-password-v2.png" className="login-icon" alt="entry--bg-password-v2.png" />
            <input id="code" type="number" placeholder="请输入验证码" className="login-text" pattern="[0-9]*" maxLength="6" value={code} onChange={(ev) => setCode(ev.target.value)}/>
          </label>
          <button className="code-button" id="code-btn" onClick={sendCode}>{codeText}</button>
        </div>
        <button id="login-btn" className="login-btn" onClick={submit}>查询</button>
      </div>
    )
  }

  function NameAndIdcard() {
    return (
      <div className="login-form">
        <label className="login-form-item" htmlFor="fullname">
          <img src="./sc-login-page-user-v2.png" className="login-icon" alt="login-user.png" />
          <input id="fullname" type="text" placeholder="请输入姓名" className="login-text" maxLength="16" value={fullname} onChange={(ev) => setFullname(ev.target.value)}/>
        </label>
        <label className="login-form-item m-t-30 m-b-60 type2" htmlFor="idcard">
          <img src="./id-card-solid.png" className="login-icon" alt="login-user.png" />
          <input id="idcard" type="text" placeholder="请输入身份证号码" className="login-text" maxLength="20" value={idCard} onChange={(ev) => setIdCard(ev.target.value)}/>
        </label>
        <button id="login-btn" className="login-btn" onClick={submit}>查询</button>
      </div>
    )
  }
  function sendCode() {
    // 发送验证码

  }
  function submit() {
    console.log('submit')
  }
}

export default Login

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

NameAndIdcard NameAndPhone 函数添加 useCallback

return部分加一个useMemo


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...