学习react第五天-状态对输入做出反应

27 阅读1分钟

React 提供了一种声明式的方式来操作 UI,描述你的组件可能处于的不同状态,并在它们之间切换以响应用户输入。

声明式 UI 与命令式 UI 相比如何

  • 当你在表单中输入内容时,“提交” 按钮将变为启用状态。
  • 当你按 “提交” 时,表单和按钮都会被禁用,并且会出现一个加载控件。
  • 如果网络请求成功,表单将隐藏,并显示 “谢谢” 消息。
  • 如果网络请求失败,则会出现错误消息,并且表单将再次启用

命令式:是因为你必须对从加载控件到按钮的每个元素进行 “命令”,告诉计算机如何更新 UI。

  • 步骤 1:识别组件的不同视觉状态

  • 步骤 2:确定触发这些状态变化的因素

  • 步骤 3:用 useState 表示内存中的状态

  • 步骤 4:删除任何非必要的状态变量

  • 步骤 5:连接事件处理程序以设置状态

      import { useState } from 'react';
    
      export default function Form() {
        const [answer, setAnswer] = useState('');
        const [error, setError] = useState(null);
        const [status, setStatus] = useState('typing');
    
        if (status === 'success') {
          return <h1>That's right!</h1>
        }
    
        async function handleSubmit(e) {
          e.preventDefault();
          setStatus('submitting');
          try {
            await submitForm(answer);
            setStatus('success');
          } catch (err) {
            setStatus('typing');
            setError(err);
          }
        }
    
        function handleTextareaChange(e) {
          setAnswer(e.target.value);
        }
    
        return (
          <>
            <h2>City quiz</h2>
            <p>
              In which city is there a billboard that turns air into drinkable water?
            </p>
            <form onSubmit={handleSubmit}>
              <textarea
                value={answer}
                onChange={handleTextareaChange}
                disabled={status === 'submitting'}
              />
              <br />
              <button disabled={
                answer.length === 0 ||
                status === 'submitting'
              }>
                Submit
              </button>
              {error !== null &&
                <p className="Error">
                  {error.message}
                </p>
              }
            </form>
          </>
        );
      }
    
      function submitForm(answer) {
        // Pretend it's hitting the network.
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            let shouldError = answer.toLowerCase() !== 'lima'
            if (shouldError) {
              reject(new Error('Good guess but a wrong answer. Try again!'));
            } else {
              resolve();
            }
          }, 1500);
        });
      }