docume"> docume"> docume">
React 词条目录
前端Wiki/React/基础/认识 React

声明式与组件化

命令式(如原生 JS / jQuery)的写法是“一步步下指令”:先找到元素、再改文字、再改样式,代码里随处可见 document.querySelector 与 innerHTML。声明式则只声明“数据与界面的对应关系”:数据是 3,界面就显示 3;改成 5 时框架自动更新,你从不碰 DOM。

组件化是把界面拆成独立积木:导航是 Navbar、列表是 TodoList、每条是 TodoItem。每个组件管自己的数据和外观,组合起来就是完整页面;某块坏了只改对应组件,不复制的界面自然不会改一漏三。

  • 声明式写的是“界面应该是结果”,框架代劳更新过程
  • 组件化带来可复用与可维护:页面 = 组件树
  • 状态(数据)一变,相关界面全部自动刷新——这就是“数据驱动视图”
HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>声明式演示</title>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const { useState } = React;

// 一个组件只用数据描述界面,没有任何 DOM 操作
function TodoList() {
  const [todos] = useState([
    { id: 1, text: '学 JSX', done: true },
    { id: 2, text: '学 useState', done: false },
    { id: 3, text: '学 useEffect', done: false },
  ]);
  return (
    <ul>
      {todos.map(t => (
        <li key={t.id} style={{ textDecoration: t.done ? 'line-through' : 'none' }}>
          {t.done ? '✅' : '⬜'} {t.text}
        </li>
      ))}
    </ul>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<TodoList />);
</script>
</body>
</html>
JS
// 同样的效果,命令式要写一串 DOM 指令(反面教材)
var todos = [
  { id: 1, text: '学 JSX', done: true },
  { id: 2, text: '学 useState', done: false },
];
var ul = document.getElementById('todoUl');   // 1. 找元素
ul.innerHTML = '';                            // 2. 清空
todos.forEach(function (t) {                  // 3. 逐条造节点
  var li = document.createElement('li');
  li.textContent = (t.done ? '✅ ' : '⬜ ') + t.text;
  if (t.done) li.style.textDecoration = 'line-through';
  ul.appendChild(li);                         // 4. 挂上去
});
// 数据一变,上面整段又得重跑一遍——声明式里你永远看不到这些
本节要点声明式让你写“结果”而非“步骤”;组件化把界面拆成可复用的函数积木。