<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>受控组件和非受控组件 on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/%E5%8F%97%E6%8E%A7%E7%BB%84%E4%BB%B6%E5%92%8C%E9%9D%9E%E5%8F%97%E6%8E%A7%E7%BB%84%E4%BB%B6/</link><description>Recent content in 受控组件和非受控组件 on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Fri, 14 Mar 2025 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/%E5%8F%97%E6%8E%A7%E7%BB%84%E4%BB%B6%E5%92%8C%E9%9D%9E%E5%8F%97%E6%8E%A7%E7%BB%84%E4%BB%B6/index.xml" rel="self" type="application/rss+xml"/><item><title>受控组件和非受控组件</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/react/react-010/</link><pubDate>Tue, 17 Dec 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/react/react-010/</guid><description>&lt;p&gt;前端开发经常会涉及表单的处理，或者其他一些用于输入的组件，比如日历组件。&lt;/p&gt;
&lt;p&gt;涉及到输入，就绕不开受控模式和非受控模式的概念。&lt;/p&gt;
&lt;p&gt;什么是受控，什么是非受控呢？&lt;/p&gt;
&lt;p&gt;想一下，改变表单值只有两种情况：&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/react/react-010/image-01.webp"&gt;&lt;/p&gt;
&lt;p&gt;用户去改变 value 或者代码去改变 value。&lt;/p&gt;
&lt;p&gt;如果不能通过代码改表单值 value，那就是非受控，也就是不受我们控制。&lt;/p&gt;
&lt;p&gt;但是代码可以给表单设置初始值 defaultValue。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/react/react-010/image-02.webp"&gt;&lt;/p&gt;
&lt;p&gt;代码设置表单的初始 value，但是能改变 value 的只有用户，代码通过监听 onChange 来拿到最新的值，或者通过 ref 拿到 dom 之后读取 value。&lt;/p&gt;
&lt;p&gt;这种就是非受控模式。&lt;/p&gt;
&lt;p&gt;反过来，代码可以改变表单的 value，就是受控模式。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/react/react-010/image-03.webp"&gt;&lt;/p&gt;
&lt;p&gt;注意，value 和 defaultValue 不一样：&lt;/p&gt;
&lt;p&gt;defaultValue 会作为 value 的初始值，后面用户改变的是 value。&lt;/p&gt;
&lt;p&gt;而一旦你给 input 设置了 value，那用户就不能修改它了，可以输入触发 onChange 事件，但是表单的值不会变。&lt;/p&gt;
&lt;p&gt;用户输入之后在 onChange 事件里拿到输入，然后通过代码去设置 value。&lt;/p&gt;
&lt;p&gt;这就是受控模式。&lt;/p&gt;
&lt;p&gt;其实绝大多数情况下，非受控就可以了，因为我们只是要拿到用户的输入，不需要手动去修改表单值。&lt;/p&gt;
&lt;p&gt;但有的时候，你需要根据用户的输入做一些处理，然后设置为表单的值，这种就需要受控模式。&lt;/p&gt;
&lt;p&gt;或者你想同步表单的值到另一个地方的时候，类似 Form 组件，也可以用受控模式。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;value 由用户控制就是非受控模式，由代码控制就是受控模式&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我们写代码试一下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-lua" data-lang="lua"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npx create&lt;span style="color:#f92672"&gt;-&lt;/span&gt;vite
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/react/react-010/image-04.webp"&gt;&lt;/p&gt;
&lt;p&gt;创建 vite + react 的项目。&lt;/p&gt;
&lt;p&gt;去掉 main.tsx 的 index.css 和 StrictMode：&lt;/p&gt;</description></item></channel></rss>