Искренне благодарен, что Вик щедро поделился этой статьей несколько недель назад, и я, наконец, решил погрузиться в нее сегодня во время лихорадочного тайфуна. Статья выходит за рамки простых заметок, она служит демонстрацией того, как я научился эффективно читать с помощью ChatGPT. Если это действительно поможет вам, я был бы очень признателен за палец вверх!

Шаг 1: получите схему/диаграмму

                         Posts
                       25 MAY 2023
                          |
                          |
         _______________________________________________________
        |                                                      |
  Introduction                                A brief history of React APIs
        |                                                      |
        |                                                      |
  _______________________________________________________________     
 |                |               |               |               |     
 | Mixins         | Higher-order  | Render props  | Hooks         |     
 |                | components    |               |               |     
 |________________________________|_______________|_______________|
                  |               |               |               |
                  |               |               |               |
      ____________|_______        |               |               |
     |           |         |      |               |       Principles behind 
 Tradeoffs   Example  Evolution   |               |       React's evolution        
             of HOCs   of Hooks   |               |               
                                  |               |               
                                  |         Understanding a
                              Tradeoffs     full-stack React 
                                    
                                           

Шаг 2: получить ключевые моменты и примеры (квадратная зона на диаграмме)

Краткая история API React

  1. Недостатки примесей: коллизия имен и неявные зависимости затрудняли управление в большой кодовой базе.
// Mixin 1: Define a theme mixin with styles for the button.
const themeMixin = {
  styles: {
    color: 'blue',
    fontSize: '16px',
  },
};

// Mixin 2: Define a hover mixin with styles for the button.
const hoverMixin = {
  styles: {
    backgroundColor: 'yellow',
  },
};

// Component using mixins
class Button extends React.Component {
  state = {
    buttonText: 'Click Me',
  };

  render() {
    const { buttonText } = this.state;

    // Apply styles from both mixins to the button.
    // However, a name collision occurs with the "styles" property.
    // The hoverMixin styles overwrite the themeMixin styles,
    // leading to unexpected behavior in the button's appearance.
    return (
      <button
        style={{
          ...themeMixin.styles,
          ...hoverMixin.styles,
        }}
      >
        {buttonText}
      </button>
    );
  }
}

2. Компоненты высшего порядка (HOC): стало проще обеспечивать общее поведение для нескольких компонентов, но конфликты имен и сложные иерархии компонентов, такие как переопределение состояния, неожиданные побочные эффекты и трудная отладка, остаются проблемами.

// Higher Order Component (HOC) to add hover functionality to components
const withHover = (Component) => {
  return class extends React.Component {
    state = {
      isHovered: false,
    };

    handleMouseEnter = () => {
      this.setState({ isHovered: true });
    };

    handleMouseLeave = () => {
      this.setState({ isHovered: false });
    };

    render() {
      const { isHovered } = this.state;

      // Wrap the original component with hover behavior
      return (
        <div
          onMouseEnter={this.handleMouseEnter}
          onMouseLeave={this.handleMouseLeave}
        >
          <Component isHovered={isHovered} {...this.props} />
        </div>
      );
    }
  };
};

// Higher Order Component (HOC) to add click functionality to components
const withClick = (Component) => {
  return class extends React.Component {
    state = {
      isClicked: false,
    };

    handleClick = () => {
      this.setState({ isClicked: true });
    };

    render() {
      const { isClicked } = this.state;

      // Wrap the original component with click behavior
      return (
        <div onClick={this.handleClick}>
          <Component isClicked={isClicked} {...this.props} />
        </div>
      );
    }
  };
};

// Component using both hover and click HOCs
class Button extends React.Component {
  render() {
    const { isHovered, isClicked } = this.props;
    return (
      <button
        style={{
          background: isHovered ? 'yellow' : 'blue',
          color: isClicked ? 'red' : 'white',
        }}
      >
        Click Me
      </button>
    );
  }
}

// Usage of nested HOCs
const ButtonWithHoverAndClick = withClick(withHover(Button));

// In the render function of the main component
return <ButtonWithHoverAndClick />;

3. Реквизиты рендеринга: обеспечивают более явный поток данных и избегают конфликтов имен, которые были обычными в двух предыдущих. Но, да, но неуклюжий аспект заключается в том, что они могут привести к глубоко вложенным пирамидам.

<Motion style={{ x: 10 }}>   
{interpolatingStyle => <div style={interpolatingStyle} />} 
</Motion>

4.Хуки: позволяют совместно размещать состояния и эффекты, упрощая кодовую базу и уменьшая вложенность.

function Example() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    console.log('Component mounted');
  }, []);
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Click Me</button>
      <p>Count: {count}</p>
    </div>
  );
}

Шаг 3: Разделите ключи на части

Разделение между классами и функциями

Часть 1. Переход от классов к функциям в React: он создает эффект разделения мозга, жонглируя ООП и функциональным программированием.

Часть 2. Компоненты Класс и функция:

  1. класс использует "this" для состояния и свойств, а функция: закрытие и декларативную синхронизацию.
  2. В функциональном программировании чистые функциине должны иметь внутреннее состояние или побочные эффекты, но в React управление состоянием необходимо для создания интерактивных пользовательских интерфейсов.

Часть 3. Проблемы построения точной ментальной модели

Опыт разработки

  1. Переход от классов к функциям и хукам повлиял на опыт.
  2. Классы имели сложную терминологию и методы привязки, а функции и хуки были упрощены, но требовали явной обработки данных.
  3. Функция React «забыть» автоматизирует предварительную компиляцию компонентов, чтобы улучшить опыт разработчиков.

Связывание состояния и логики с React

  1. Ориентация на приложения и компоненты: различные способы управления состоянием в React. App использует глобальные хранилища, такие как Redux, в то время как Component использует хуки, такие как useState для состояния внутри компонентов.
  2. Глобальные монолитные хранилища: управление состоянием с помощью централизованных решений, таких как Redux или MobX. Может привести к сложным кодовым базам.
  3. Совместное размещение с хуками: размещение состояния и логики непосредственно внутри компонентов с помощью хуков. Улучшает организацию кода и аргументацию.
  4. Переход от отдельного состояния и представления: переход от отдельного состояния и представления к более тесному взаимодействию в компонентах React.
  5. Улучшение локального мышления и переносимости: перехватчики и состояние совместного размещения улучшают понимание и позволяют повторно использовать компоненты.
// Global monolithic store example
const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    case 'DECREMENT':
      return { ...state, count: state.count - 1 };
    default:
      return state;
  }
}

const App = () => {
  const [state, dispatch] = React.useReducer(reducer, initialState);

  return (
    <div>
      <h1>Count: {state.count}</h1>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
    </div>
  );
}
// Component-centric approach with hooks
const Counter = () => {
  const [count, setCount] = React.useState(0);

  const handleIncrement = () => setCount(count + 1);
  const handleDecrement = () => setCount(count - 1);

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={handleIncrement}>Increment</button>
      <button onClick={handleDecrement}>Decrement</button>
    </div>
  );
}

const App = () => {
  return (
    <div>
      <Counter />
    </div>
  );
}

Шаг 4: получить заключение с заголовком и ключами

Принципы эволюции React

  1. Взаимодействие пользователей с API: баланс между конечными пользователями и разработчиками. React отдает приоритет пользовательскому опыту, предоставляя гибкий API.
  2. API важнее реализаций. Концепция высокоуровневого API «компонента» остается стабильной, несмотря на изменения внутренней реализации.
  3. Сосредоточьтесь на правильных примитивах. Построение на прочной основе с помощью компонентной модели обеспечивает лучшую компоновку и переносимость.
  4. Переносимость и совместное размещение. Компоненты фиксируют совместное размещение задач, упрощая поддержку и отладку кода.
  5. Переход от классов к хукам: переход от логики на основе классов к компонуемым функциям внутри компонентов.

и более…

Шаг 5: Для сравнения используйте табличную форму

Понимание полного стека React

| Directive      | Purpose                              | Usage                                                 |
|----------------|--------------------------------------|-------------------------------------------------------|
| "use client"   | Marks client-specific code           | Placed at the top of a file to indicate client code   |
|                |                                      | Modules are considered part of the client bundle      |
|                |                                      | Components with "use client" can run on the server    |
|                |                                      | Used for generating initial HTML or static site gen.  |
|----------------|--------------------------------------|-------------------------------------------------------|
| "use server"   | Used in server components for RPC    | Placed at the top of an action function               |
|                | (Remote Procedure Call)              | Tells the compiler to keep it on the server           |
|                |                                      | Not included in the client bundle                     |
|----------------|--------------------------------------|-------------------------------------------------------|
| "server-only"  | Marks code for server-only use       | Ensures code is only used on server                   |
|                |                                      | Helps prevent accidentally sending client code        |
|                |                                      | Used to mark boundaries in shared module graph        |
|----------------|--------------------------------------|-------------------------------------------------------|