前端框架学习-React(一)

React 应用程序是由组件组成的。

  • react 程序是用的jsx语法,使用这种语法的代码需要由babel进行解析,解析成js代码。

    jsx语法:

    1. 只能返回一个根元素

    2. 所有的标签都必须闭合(自闭和或使用一对标签的方式闭合)

    3. 使用驼峰式命名法给大部分属性命名如:className

    4. 大写字母开头的标签一般都是组件

    5. jsx标签的属性,使用引号传递字符串,使用一组{ }传递js变量,且大括号中可以写js的表达式,也可以传递使用个另外一对额外的大括号包裹对象。

    6. 标签中可以使用三目运算符

      在 JSX 中,{cond ? <A /> : <B />} 表示 “当 cond 为真值时, 渲染 <A />,否则 <B />

      在 JSX 中,{cond && <A />} 表示 “当 cond 为真值时, 渲染 <A />,否则不进行渲染”

      return (
        <li className="item">
          {
               
               isPacked ? name + ' ✔' : name}
        </li>
      );
      
    7. 渲染列表:使用map()方法生成一组相似组件,使用filter()方法来筛选数组

      const listItems = chemists.map(person =>
        <li>...</li> // 隐式地返回!
      );
         
      const listItems = chemists.map(person => {
               
                // 花括号
        return <li>...</li>;
      });
      
  • 组件引入语法用到了ES6的模块化编程语法

    1. 解构赋值语法:可以将数组中的值或对象的属性取出,赋值给其他变量。

    2. 展开运算符:

      function Profile({
                
                 person, size, isSepia, thickBorder }) {
               
               
        return (
          <div className="card">
            <Avatar
              person={
               
               person}
              size={
               
               size}
              isSepia={
               
               isSepia}
              thickBorder={
               
               thickBorder}
            />
          </div>
        );
      }
      {
               
               /* 关于Avatar那一部分可以写成 */}
      <Avatar {
               
               ...props} />
      
  • React 三大元素:

    • State对象(要将state视为只读的)

      在数据发生改变之后页面上的内容才会重新渲染、

      • 设置 state 不会更改现有渲染中的变量,会请求一次新的渲染。
      • React 将 state 存储在组件之外,就像在架子上一样。
      • 当你调用 useState 时,React 会为你提供该次渲染 的一张 state 快照。

      更新state对象时要传递一个新的值,即使时一个json对象。

      • 你可以使用这样的 {...obj, something: 'newValue'} 对象展开语法来创建对象的拷贝。

      更新state中的数组:

      推荐使用(会返回一个新数组)
      添加元素 concat,[…arr]
      删除元素 filter,slice
      替换元素 map
      排序 先将数组复制一份儿

      可以使用 Immer 来保持代码简洁。

      相同UI树上的元素的State将会被保留,位置不同的组件会使state重置

      • 你可以通过为一个子树指定一个不同的 key 来重置它的 state。
    • props对象

      在标签上添加属性,即可给组件添加prop属性。在子组件中可以通过props读取到对应的属性,解构赋值时可以给一个默认值

      function Avatar({
                
                 person, size = 100 }) {
               
               
        // ...
      }
      

      组件间共享状态:可以通过状态提升的方式,让后再通过props传递给子组件。

      通过context上下文传递参数

      1. 创建context

        import {
                   
                    createContext } from 'react';
        export const LevelContext = createContext(1);
        
      2. 使用context

        {
                   
                   /* 组件会使用 UI 树中在它上层最近的那个 <LevelContext.Provider> 传递过来的值。 */}
        import {
                   
                    LevelContext } from './LevelContext.js';
        const level = useContext(LevelContext);
        
      3. 提供context

        {
                   
                   /* 在父组件中设定对应的值 */}
        <section className="section">
            <LevelContext.Provider value={
                   
                   level}>
          		{
                   
                   children}
            </LevelContext.Provider>
        </section>
        
    • ref对象

  • React的交互:

    • 给元素的事件传递一个函数,而调用一个函数。

      <button onClick={
              
              handleClick}> {
              
              /* 正确 */}
      <button onClick={
              
              handleClick()}>{
              
              /* 错误 */}
      
  • 在 React 中,useState 以及任何其他以“use”开头的函数都被称为 Hook

    • 使用useImmerReducer可以将通知同一个state的方法,组织到一起。提高代码的可读性。

      • useState转化为useReducer
        1. 通过事件处理函数 dispatch actions;
        2. 编写一个 reducer 函数,它接受传入的 state 和一个 action,并返回一个新的 state;
        3. 使用 useReducer 替换 useState
      import {
              
               useImmerReducer } from 'use-immer';
      import AddTask from './AddTask.js';
      import TaskList from './TaskList.js';
      
      function tasksReducer(draft, action) {
              
              
        switch (action.type) {
              
              
          case 'changed': {
              
              
            const index = draft.findIndex((t) => t.id === action.task.id);
            draft[index] = action.task;
            break;
          }
          case 'deleted': {
              
              
            return draft.filter((t) => t.id !== action.id);
          }
          default: {
              
              
            throw Error('未知 action:' + action.type);
          }
        }
      }
      
      export default function TaskApp() {
              
              
        const [tasks, dispatch] = useImmerReducer(tasksReducer, initialTasks);
        function handleChangeTask(task) {
              
              
          dispatch({
              
              
            type: 'changed',
            task: task,
          });
        }
        function handleDeleteTask(taskId) {
              
              
          dispatch({
              
              
            type: 'deleted',
            id: taskId,
          });
        }
        return (
          <>
            <h1>布拉格的行程安排</h1>
            <AddTask onAddTask={
              
              handleAddTask} />
            <TaskList
              tasks={
              
              tasks}
              onChangeTask={
              
              handleChangeTask}
              onDeleteTask={
              
              handleDeleteTask}
            />
          </>
        );
      }
      let nextId = 3;
      const initialTasks = [
        {
              
              id: 0, text: '参观卡夫卡博物馆', done: true},
        {
              
              id: 1, text: '看木偶戏', done: false},
        {
              
              id: 2, text: '打卡列侬墙', done: false},
      ];
      
      

猜你喜欢

转载自blog.csdn.net/u013795102/article/details/132345653