0

React 和TypeScript 练习笔记(一)——简单交互与CP模式

 1 year ago
source link: https://nakeman.cn/blog/react-typescript-container-presenter-pattern/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

React 和TypeScript 练习笔记(一)——简单交互与CP模式

本系列为Lemoncode开源项目(其中之一)练习总结,原项目共有15个练习,经我的分析,主要可归五个练习:

第一个练习由前6 个子练习组成,目的归结起来主要为了展示 最经典的React 组件模式——CP模式。

00 Boiler plate
01 Hello React
02 Properties
03 State
04 Callback
05 Refactor
06 Enable

CP模式就是 Container-Presenter模式(容器与展示组件模式)。前端开发中最常见的任务莫过于 组件的粒度(或功能分配)的设计,就是 将一个大组件分拆为多个子组件的最佳实践。例如 “在一个VX组件 中应该将状态放在组件树的哪里最合适?”,“lifting state up” 就是社区的一种经验见解,其实本质是 Container-Presenter模式。

Container-Presenter模式 是种 父子关系的组件结构,父组件是一个容器组件,负责初始化交互状态,保持交互状态,和定义操作状态的逻辑(一般是交互事件处理,也不尽然); 子组件 是一展示型组件,负责交互输出——将交互结果(状态)渲染出来,也负责接受用户交互输入。

由于被分割了,组合它们是靠React props技术,包括data props 和 callback props。

练习项目的交互功能 非常的简单,就是 用一个输入框接受用户的键盘输入,点击界面按键(鼠标输入)后 更新状态输出来,没有任何处理。

项目技术遗漏

本练习项目还有一些不太明显的技术要点:

第一,双向绑定和 受控组件

React 没有自动双向绑定的概念,只有受控组件,并且需要手动配置;由于功能是编辑完后点击后才渲染出来,所以 输入框的受控状态 不是渲染出来的那个状态(看源码容器组件有两个状态值),并且每编辑输入框一次,组件都重渲染;

第二,交互辅助状态

组件实现一项常见的用户友好体验的交互功能,就是在合适时候,更新按键才可用。由于逻辑较简单,此功能不需一个额外的 交互状态,它是 输入框状态的 派生状态(7第4和24行)。

交互流程,逻辑比较 复杂的时候,就会出现交互辅助状态,来提高用户交互体验。

项目结构分析

├── package.json
├── src
│   ├── app.tsx // 顶层父组件(容器组件)
│   ├── hello.tsx // 交互状态输出的子组件(展示组件)
│   ├── index.html //
│   ├── index.tsx //
│   └── nameEdit.tsx // 交互状态输入的子组件(展示组件)
├── tsconfig.json
└── webpack.config.js

项目代码简要分析

app.tsx

import * as React from "react";
import { HelloComponent } from "./hello";
import { NameEditComponent } from "./nameEdit";

export const App = () => {
  const [name, setName] = React.useState("defaultUserName");
  const [editingName, setEditingName] = React.useState("defaultUserName");

  const loadUsername = () => {  };

  React.useEffect(() => {    loadUsername();  }, []);

  const setUsernameState = () => {
    setName(editingName);
  };

  return (
    <>
      <HelloComponent userName={name} />
      <NameEditComponent
        editingName={editingName}
        onNameUpdated={setUsernameState}
        onEditingNameUpdated={setEditingName}
        disabled={editingName === "" || editingName === name}
      />
    </>
  );
};

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK