React学习记录

一、React入门:从"搭积木"开始理解组件化

1.1 为什么说React像乐高?

刚接触React时,都说"组件化开发就像搭积木",我盯着满屏的JSX语法一脸懵。直到自己写出第一个组件才恍然大悟——原来每个按钮都是独立封装的乐高积木块!

// 第一个组件:会卖萌的按钮
function CuteButton({ text }) {
  return (
    <button style={{ 
      padding: '10px 20px',
      borderRadius: '20px',
      background: 'pink',
      border: 'none'
    }}>
      🎀 {text} 🎀
    </button>
  );
}

// 使用组件
<CuteButton text="点击领取小猫" />

新手踩坑实录:
有次我把组件命名为button(全小写),结果死活渲染不出来。后来才明白组件名必须大写字母开头,这是JSX的强制约定!这种细节在初学阶段最容易让人抓狂😫

1.2 JSX:当HTML遇见JavaScript

第一次看到JSX时,我的内心是崩溃的——这既不像HTML也不像纯JS。直到在项目中实现动态列表,才体会到它的妙处:

function TodoList() {
  const todos = ['买猫粮', '撸代码', '给主子铲屎'];
  
  return (
    <ul className="todo-list">
      {todos.map((item, index) => (
        // 注意这里需要key属性!
        <li key={index} style={{ color: index === 0 ? 'red' : '#333' }}>
          🐾 {item}
        </li>
      ))}
    </ul>
  );
}

避坑指南:

列表渲染必须加key属性
行内样式要写成对象形式:{{ }}双括号不是手抖!

二、组件进阶:打造高复用性代码块

2.1 组件通信的三种姿势

2.1.1 Props传参:父子组件对话

// 父组件
<CatProfile 
  name="奥利奥" 
  age={2} 
  onFeed={() => console.log('投喂成功🍗')}
/>

// 子组件
function CatProfile({ name, age, onFeed }) {
  return (
    <div>
      <h3>{name} · {age}</h3>
      <button onClick={onFeed}>喂食按钮</button>
    </div>
  );
}

2.1.2 Context:跨层级传值

实现主题切换的经典场景:

const ThemeContext = createContext('light');

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar() {
  const theme = useContext(ThemeContext);
  return <div style={{ background: theme === 'dark' ? '#333' : '#fff' }}>...</div>;
}

2.1.3 自定义Hook:更优雅的复用

封装一个获取鼠标位置的Hook:

function useMousePosition() {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  useEffect(() => {
    const updatePosition = e => setPosition({ x: e.clientX, y: e.clientY });
    window.addEventListener('mousemove', updatePosition);
    return () => window.removeEventListener('mousemove', updatePosition);
  }, []);

  return position;
}

// 在组件中使用
function CursorTracker() {
  const { x, y } = useMousePosition();
  return <div>鼠标坐标:({x}, {y})</div>;
}

三、状态管理:从useState到全局状态管控

3.1 状态管理进化论

方案 适用场景 新手友好度
useState 简单组件内部状态 ⭐⭐⭐⭐⭐
useReducer 复杂状态逻辑 ⭐⭐⭐⭐
Context API 跨组件层级传递 ⭐⭐⭐
Redux 大型应用全局状态 ⭐⭐

3.2 购物车案例实战

function Cart() {
  const [items, dispatch] = useReducer(cartReducer, []);
  
  // 加入购物车
  const addItem = item => dispatch({ type: 'ADD_ITEM', payload: item });
  
  // 移除商品
  const removeItem = id => dispatch({ type: 'REMOVE_ITEM', payload: id });

  return (
    <div>
      {items.map(item => (
        <div key={item.id}>
          {item.name} - 
          <button onClick={() => removeItem(item.id)}>🗑️</button>
        </div>
      ))}
      <button onClick={() => addItem({ id: Date.now(), name: '猫罐头' })}>
        添加商品
      </button>
    </div>
  );
}

function cartReducer(state, action) {
  switch (action.type) {
    case 'ADD_ITEM':
      return [...state, action.payload];
    case 'REMOVE_ITEM':
      return state.filter(item => item.id !== action.payload);
    default:
      return state;
  }
}

新手常见误区:

直接修改state对象(必须返回新对象!)
在条件语句或循环中使用Hook
忘记添加依赖项导致useEffect无限循环

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萝卜·

期待大佬们的鼓励与支持~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值