推荐两个好用的 React 库以及使用后的感想

1,214 阅读2分钟

Formik

github地址

墙裂推荐

直接上例子吧

    <Formik
      initialValues={{ email: '', password: '' }}
      validate={values => {
        let errors = {};
        if (!values.email) {
          errors.email = 'Required';
        } else if (
          !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
        ) {
          errors.email = 'Invalid email address';
        }
        return errors;
      }}
      onSubmit={(values, { setSubmitting }) => {
        setTimeout(() => {
          alert(JSON.stringify(values, null, 2));
          setSubmitting(false);
        }, 400);
      }}
    >
      {({
        values,
        errors,
        touched,
        handleChange,
        handleBlur,
        handleSubmit,
        isSubmitting,
        /* and other goodies */
      }) => (
        <form onSubmit={handleSubmit}>
          <input
            type="email"
            name="email"
            onChange={handleChange}
            onBlur={handleBlur}
            value={values.email}
          />
          {errors.email && touched.email && errors.email}
          <input
            type="password"
            name="password"
            onChange={handleChange}
            onBlur={handleBlur}
            value={values.password}
          />
          {errors.password && touched.password && errors.password}
          <button type="submit" disabled={isSubmitting}>
            Submit
          </button>
        </form>
      )}
    </Formik>

上面可以看到 Formik 只负责提供表单操作相关的 props,并不直接去影响 UI,所以这样的话使用者就可以自由的定义 UI 和交互该如何展现,而相关的表单操作可以直接使用 Formik 提供的 props 即可。

在表单验证上个人推荐搭配 yup 食用更佳。

Downshift

github地址

这是一个制作 Select 相关的组件库,同样它也是提供给使用者下拉选择或者搜索选择之类的 props,UI 由使用者自定义。

感悟

对于使用上述两个库后自己对组件的设计也多了些想法,一个优秀的前端库不一定会具备最优秀 UI,但是一定具备让使用者使用起来感觉舒服的 API,所以基于此我自己也设计了一个关于上传的组件,目前在公司内部项目中进行了使用。

example

    <FileUpload
        upload={upload}
        files={files}
        accept={config.accept}
        multiple={!!config.multiple}
        onStatusChange={(files) => {
          const uploadedFiles = files.filter(file => file.status === FileUploadStatus.UPLOADED)
          const changeFiles = uploadedFiles.map(getValueFromFiles)
          if (config.multiple) {
            setFieldValue(changeFiles)
          } else {
            setFieldValue(changeFiles[0])
          }
        }}
      >
        {(fileRenderProps) => {
          return (
            <FilePreview
              fileRenderProps={fileRenderProps}
              multiple={!!config.multiple}
            />
          )
        }}
    </FileUpload>

我提供了一个 FileUpload 组件,组件对其 children 提供了 fileRenderProps,里面包含当前上传的 files,拖拽相关的 dndProps,拖拽的状态 dndStatus,还有就是上传的 showOpenDialog

interface IFileUploadRenderProps {
  readonly files: IUploadFileProps[]
  readonly dndProps: IDNDProps
  readonly dndStatus: IDNDStatus
  showOpenDialog(): void
  removeAllFile(): void
}

以及上面还提供了一个比较通用的 FilePreview 组件用来展示上传的文件队列,在 FileUpload 组件的 children 中我们可以自由定义上传按钮或者上传的拖拽区域的交互和 UI

最后放上几张示例图

结语

第一次写文章,有不好的地方请包涵,哈哈哈。