React 提供了一种操作 UI 的声明性方式。您无需直接操作 UI 的各个部分,而是描述组件可能处于的不同状态,并在它们之间切换以响应用户输入。
声明式 UI 与命令式 UI 的比较
在设计 UI 交互时,可能会考虑 UI 如何响应用户操作而更改。考虑一个允许用户提交答案的表单:
- 当您在表单中键入内容时,“提交”按钮将启用。
- 当您按“提交”时,表单和按钮都会被禁用,并出现一个微调器。
- 如果网络请求成功,表单将被隐藏,并显示“谢谢”消息。
- 如果网络请求失败,则会显示一条错误消息,并且表单将再次启用。
在命令式编程中,上述内容直接对应于如何实现交互。您必须编写确切的指令来操作 UI,具体取决于刚刚发生的事情。这是另一种思考方式:想象一下,在一辆车里骑在某人旁边,然后轮流告诉他们去哪里。
他们不知道你想去哪里,他们只是听从你的命令。(如果你把方向弄错了,你最终会来错地方!它之所以被称为命令式,是因为你必须“命令”每个元素,从微调器到按钮,告诉计算机如何更新 UI。
在这个命令式 UI 编程的例子中,表单是在没有 React 的情况下构建的。它只使用浏览器 DOM:
async function handleFormSubmit(e) { e.preventDefault(); disable(textarea); disable(button); show(loadingMessage); hide(errorMessage); try { await submitForm(textarea.value); show(successMessage); hide(form); } catch (err) { show(errorMessage); errorMessage.textContent = err.message; } finally { hide(loadingMessage); enable(textarea); enable(button); } } function handleTextareaChange() { if (textarea.value.length === 0) { disable(button); } else { enable(button); } } function hide(el) { el.style.display = 'none'; } function show(el) { el.style.display = ''; } function enable(el) { el.disabled = false; } function disable(el) { el.disabled = true; } function submitForm(answer) { // Pretend it's hitting the network. return new Promise((resolve, reject) => { setTimeout(() => { if (answer.toLowerCase() === 'istanbul') { resolve(); } else { reject(new Error('Good guess but a wrong answer. Try again!')); } }, 1500); }); } let form = document.getElementById('form'); let textarea = document.getElementById('textarea'); let button = document.getElementById('button'); let loadingMessage = document.getElementById('loading'); let errorMessage = document.getElementById('error'); let successMessage = document.getElementById('success'); form.onsubmit = handleFormSubmit; textarea.oninput = handleTextareaChange;
<form id="form"> <h2>City quiz</h2> <p> What city is located on two continents? </p> <textarea id="textarea"></textarea> <br /> <button id="button" disabled>Submit</button> <p id="loading" style="display: none">Loading...</p> <p id="error" style="display: none; color: red;"></p> </form> <h1 id="success" style="display: none">That's right!</h1> <style> * { box-sizing: border-box; } body { font-family: sans-serif; margin: 20px; padding: 0; } </style>
对于孤立的示例来说,操作 UI 已经足够好了,但在更复杂的系统中,管理起来会成倍增加。想象一下,更新一个充满不同表单的页面,就像这个一样。添加新的 UI 元素或新的交互需要仔细检查所有现有代码,以确保没有引入 bug(例如,忘记显示或隐藏某些内容)。
React 就是为了解决这个问题而构建的。
在 React 中,你不会直接操作 UI,这意味着你不会直接启用、禁用、显示或隐藏组件。取而代之的是,你声明了你想要显示的内容,React 会弄清楚如何更新 UI。