IT, 筆記

Learn ReactJS 17 + react-jsonschema-form + typescript

I have stopped the development using React for several years. Now, I would like to pick up some development skills. However, I found my React skill was outdated. As I am going to learn TypeScript and Jsonschema form, I would give a try with these frameworks altogether.

First off, I follow this: https://reactjs.org/tutorial/tutorial.html#setup-option-2-local-development-environment

Environment Setup

Current Env.: WSL2 + Ubuntu + NodeJS(v10.19.0) + TypeScript (3.8.3)

Update/Upgrade to latest NodeJS 14 (most latest LTS – Fermium 14.15.0) (ref: Install Node.js 14 on Ubuntu 20.04/18.04 & Debian 10/9)

$ sudo su -
# apt upgrade
# curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -
# apt -y install nodejs

Now, the NodeJS is v14.15.0

Optionally, install development tools:

# apt -y install gcc g++ make
# curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
# echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
# apt update && sudo apt install yarn
# npm install -g typescript@latest

Now, yarn is install, version is: 1.22.5; typescript version is 4.0.5

Follow Setup Option 2: Local Development Environment to create app

Create an Empty App:

$ cd {some project parent folder}
$ npx create-react-app testapp1
$ cd testapp1/src
$ rm -Rf *

Create helloworld index.js:

import React from 'react';
import ReactDOM from 'react-dom';

function Hi() {
    return <div>Hello World!</div>;
}

ReactDOM.render(<Hi />, document.querySelector('#root'));

Start and test:

$ yarn start

Change to react-jsonschema-form. Install the dependence:

$ yarn add @rjsf/core

Replace index.js content with below:

import React from 'react';
import ReactDOM from 'react-dom';
import Form from "@rjsf/core";

const schema = {
    title: "Todo",
    type: "object",
    required: ["title"],
    properties: {
        title: { type: "string", title: "Title", default: "A new task" },
        done: { type: "boolean", title: "Done?", default: false }
    }
};

const log = (type) => console.log.bind(console, type);

function MyFrom() {
    return <Form schema={schema}
        onChange={log("changed")}
        onSubmit={log("submitted")}
        onError={log("errors")} />;
}

ReactDOM.render(<MyFrom />, document.querySelector('#root'));

Start and test again. The form should be shown.

Switch to TypeSript

Create typescript react project and test:

$ npx create-react-app testapp2 --template typescript
$ cd testapp2
$ yarn add typescript @types/node @types/react @types/react-dom @types/jest
$ yarn start

Change to HelloWorld code:

$ cd {some project parent folder}
$ cd testapp2/src
$ rm -Rf *

Create index.tsx:

import React from 'react';
import ReactDOM from 'react-dom';

function Hi() {
    return <div>Hello World!</div>;
}

ReactDOM.render(<Hi />, document.querySelector('#root'));

Start and test:

$ yarn start

Change to react-jsonschema-form. Install the dependence:

$ yarn add @rjsf/core

Replace index.tsx content with below:

import React from "react";
import ReactDOM from "react-dom";
import Form from "@rjsf/core";
import { JSONSchema7 } from "json-schema";

const schema: JSONSchema7 = {
  title: "Todo",
  type: "object",
  required: ["title"],
  properties: {
    title: { type: "string", title: "Title", default: "A new task" },
    done: { type: "boolean", title: "Done?", default: false },
  },
};

const log = (type: string) => console.log.bind(console, type);

function MyFrom() {
  return (
    <Form
      schema={schema}
      onChange={log("changed")}
      onSubmit={log("submitted")}
      onError={log("errors")}
    />
  );
}

ReactDOM.render(<MyFrom />, document.querySelector("#root"));

Note for Typescript for react-jsonschema-form

– Declare JSONSschme type for the schema (in the above example, it is JSONSchema7

Okay, the quick start are done.

Make some style

The react-jsonschema-form core supports Bootstrap 3 by default. Since React project come without supporting bootstrap, we need to add bootstrap in the react project:

$ yarn add react-bootstrap bootstrap

Current version of bootstrap is 4. Therefore we need to change the theme for react-jsonschema-form to Bootstrap 4:

$ yarn add @rjsf/bootstrap-4

And change the content in index.tsx to:

import React from "react";
import ReactDOM from "react-dom";
import Form from "@rjsf/bootstrap-4";
import { JSONSchema7 } from "json-schema";

import "bootstrap/dist/css/bootstrap.min.css";

const schema: JSONSchema7 = {
  title: "Todo",
  type: "object",
  required: ["title"],
  properties: {
    title: { type: "string", title: "Title", default: "A new task" },
    done: { type: "boolean", title: "Done?", default: false },
  },
};

const log = (type: string) => console.log.bind(console, type);

function MyFrom() {
  return (
    <Form
      schema={schema}
      onChange={log("changed")}
      onSubmit={log("submitted")}
      onError={log("errors")}
    />
  );
}

ReactDOM.render(<MyFrom />, document.querySelector("#root"));

Use SASS and set some css (See: https://create-react-app.dev/docs/adding-a-sass-stylesheet/):

$ yarn add node-sass

Update index.tsx:

// From:
// import "bootstrap/dist/css/bootstrap.min.css";

// To:
import "./index.scss";

Create the scss file index.scss

@import-normalize; /* bring in normalize.css styles */

// Override bootstrap setting
$theme-colors: (
  primary: orange
) !default;

// These are the defaults, but you can override any values
$font-family-sans-serif: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !default;
$font-family-serif:      Georgia, "Times New Roman", Times, serif !default;
$font-family-monospace:  Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default;
$font-family-base:       $font-family-monospace !default;

@import "~bootstrap/scss/bootstrap";

body {
  margin: 15px;
}

The result looks better now.

Override bootstrap using scss

To orverride bootstrap in React App via SCSS, (1) Create a scss and let it does the rest; (2) Set the SCSS variable, end with !default to override the bootstrap variable; (3) import bootstrap scss (i.e. 「bootstrap/scss/bootstrap」)

發表回覆

你的電郵地址並不會被公開。 必要欄位標記為 *