20201121のReactに関する記事は7件です。

create-react-app×TypeScriptでTypeError: Cannot assign to read only property 'jsx' of object '#<Object>'のエラーが出る

はじめに

create-react-appでTypeScriptのプロジェクトを始めた時に、yarn startすると、
TypeError: Cannot assign to read only property 'jsx' of object '#'が出たので解決策を記しておきます

内容

$ npx create-react-app sample --template typescript
$ cd sample
$ yarn start

でreactのプロジェクトを開始しようとした時に、

/Users/yourname/sample/node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js:239
      appTsConfig.compilerOptions[option] = value;
                                          ^

TypeError: Cannot assign to read only property 'jsx' of object '#<Object>'
    at verifyTypeScriptSetup (/Users/yourname/sample/node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js:239:43)
    at Object.<anonymous> (/Users/yourname/sample/node_modules/react-scripts/scripts/start.js:31:1)
    at Module._compile (internal/modules/cjs/loader.js:1137:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
    at Module.load (internal/modules/cjs/loader.js:985:32)
    at Function.Module._load (internal/modules/cjs/loader.js:878:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

のエラーが出ました。

解決策としましては、

$ yarn add typescript@4.0.5

そして、以下の変更を加えます。

tsconfig.json
  -  "jsx": "react-jsx"
  +  "jsx": "react"

これで動くはずです!

なお、詳しくは https://github.com/facebook/create-react-app/issues/10110 で書かれているので気になる方は読んでみてください

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Reactでmap型の要素をループしてテーブルを作成する

コード

  • 要素数的なものは取れないのかな、、、
  • tableはテーブル全体
  • thはテーブルの見出し(table head cell)
  • tdはテーブル内のデータ(table data)
  • trはテーブルの横の定義(table row)
  • アロー関数のループの中でテーブルを定義する感じ
                    <div>
                        <table border="1" width="500" cellPadding="0">
                            <th>No</th>
                            <th>Name</th>
                            <th>Status</th>
                                {this.state.pods.map((pod) =>
                                    <tr>
                                        <td>{pod.id}</td>
                                        <td>{pod.metadata.name}</td>
                                        <td>{pod.status.phase}</td>
                                    </tr>
                                )}
                        </table>
                    </div>

画面

image.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

create-react-appコマンド無しでcreate-react-appっぽい環境をつくる

タイトル通り create-react-appコマンド無しでcreate-react-appっぽいreact + typescriptの環境構築していきます。 今回、create-react-appぽいとは次のようなことを指します。

  • とりあえずts,tsxが動く
  • yarn buildでbuildファイルを生成する。
  • yarn startでローカルサーバーが自動で起動する。
  • ローカルサーバーが起動中、編集すると、自動でリロードされる(ホットリロード)

登場人物ややこしすぎ問題

とにかく構築にいろいろなパターンが多い + デファクトがよくわからない。1
本記事ではwebpack + ts-loaderの構成で構築していこうと思います。(babel-loaderを使わないパターンです)
そのため、対象となる読者は以下のとおりです。

・始めたてで、とにかく動かしてみたいだけ。
・細かいpolyfillは考えていない。
・作るものが小規模だ。(個人の練習アプリ程度) 

環境

環境は以下の通りです。yarn使います。

$ node -v
v13.11.0
$ yarn -v
1.22.4 

init

まずはじめにpackage.jsonを生成します。

$ yarn init -y                //-yで対話をスキップ

パッケージのインストール

次にwebpackともろもろのインストールを行います。

$ yarn add -D webpack@4.43.0 webpack-cli@3.3.12 webpack-dev-server@3.11.0 html-webpack-plugin typescript ts-loader

正常な動作を確認しているのは上記のバージョンのwebpack,webpack-cli,webpack-dev-serverのみです。バージョンを指定しない場合webpack v5系がインストールされるので注意してください。(2020年11/21日現在)2

  • webpack  ・・・・みんな大好きモジュールバンドラーの本体
  • webpack-cli ・・・・webpackコマンドがshellで使える様になる。package.jsonのscriptsにこのコマンドを割り当てることが多い
  • webpack-dev-server ・・・・開発サーバー用
  • html-webpack-plugin ・・・・必須ではないです。webpackがバンドルと一緒に.htmlも吐き出してくれます。自前でhtmlファイルを用意してもいいですが、使い方がとても簡単かつ楽なので筆者はいつもwebpackにまかせてます。
  • typescript ・・・・いつものあいつ
  • ts-loader ・・・・webpackがバンドルを作成するときにtsx—> jsx —> jsとコンパイルしてくれます。babel-loaderとごっちゃになってハゲそうになった。

scriptsの設定

先にpackage.jsonにscriptsを設定しておきましょう。

"scripts":{
   // dev-serverをdevelopmentモードで起動
   "start": "webpack-dev-server --config ./webpack.config.js --mode development”,   
   // productionモードでbuildファイルの出力
   "build":"webpack --mode production"
  } 

reactのインストール

次にreactと型定義ファイルをインストールします。こちらの詳細は割愛します。

$ yarn add react react-dom
$ yarn add -D @types/react @types/react-dom

ここから諸々のファイルを作成していきます。最終的なディレクトリ構成を載せておきます。

├── build       //buildディレクトリ
│   ├── bundle.js
│   └── index.html
├── package.json
├── src
│   ├── index.tsx  //エントリーポイント
│   └── template   // htmlpluginのテンプレート
│       └── index.html       
├── tsconfig.json
├── webpack.config.js
└── yarn.lock

webpack.config.js

webpack.config.jsを作成します。

// webpack.config.js
const path = require("path");

//htmlプラグインのための呪文
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  mode: "development",
  entry: {
    bundle: "./src/index.tsx", // エントリーファイルの位置
  },
  output: {
    filename: "[name].js",   // 今回はbundle.jsで吐き出される(entryで指定)
    path: path.join(__dirname, "build"), // buildという名前のbuildディレクトリを吐き出す
    chunkFilename: "[name].js",//今回は触れません 
  },
  devServer: {
    contentBase: path.join(__dirname, "build"),
    compress: true,
    port: 8080,
    open: true,        //yarn start コマンドを入力すると自動でブラウザに遷移します。
    historyApiFallback: true,
  },
  module: {
    rules: [
      {
        test: /\.ts(x?)$/,    //.ts または.tsxに対して
        loader: "ts-loader",  // ts-loaderを使用
      },
    ],
  },
  resolve: {
    extensions: [".ts", ".js", ".tsx", ".jsx"],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: `${__dirname}/src/template/index.html`, //テンプレートファイルの場所
      filename: "index.html",                                                      //テンプレートファイルの名前
      inject: "body",                                                             //bodyタグの直前でwebpackのバンドルを埋め込み
    }),
  ],
};

おまけ: 本当はwebpackのprodモードとdevモードの環境は個別に設定することが推奨されています。詳しくは公式ドキュメントを参照してください。今回はscriptsで無理やり分けてます。

tsconfig.json

次にtsconfig.jsonを作成します。ts-loaderはこのファイルの設定に従います。
必ず "jsx":"react"を指定しましょう。
ほぼデフォルトのコピペです。細かいのはお好みで。

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "esnext",
    "resolveJsonModule": true,
    /* Basic Options */
    "allowJs": false /* Allow javascript files to be compiled. */,
    "jsx": "react" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */,
    "sourceMap": true /* Generates corresponding '.map' file. */,
    "outDir": "/build" /* Redirect output structure to the directory. */,
    "isolatedModules": true /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */,
    /* Strict Type-Checking Options */
    "strict": true /* Enable all strict type-checking options. */,
    "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
    "strictNullChecks": true /* Enable strict null checks. */,

    /* Additional Checks */
    "noUnusedLocals": true /* Report errors on unused locals. */,
    "noUnusedParameters": true /* Report errors on unused parameters. */,
    "noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
    "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
    /* Module Resolution Options */
    "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
    relative to the 'baseUrl'. */
    structure of the project at runtime. */
    "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
    "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,

    /* Advanced Options */
    "skipLibCheck": true /* Skip type checking of declaration files. */,
    "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
  },
  "include": ["src"]
}

仕上げ

.tsxとhtmlのテンプレートを作成します。

// src/index.tsx
import React from "react";
import ReactDOM from "react-dom";
ReactDOM.render(<h1>hello</h1>, document.getElementById("root"));
// src/template/index.html
// ! + tab キーで作ってます。
// <div id = "root"></div>を忘れずに

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id='root'></div>
</body>

</html>

ここで、

$ yarn start 

するとindex.tsxの内容が描画されると思います。

ソースコードはこちら


  1. ts-loaderでjsxまでコンパイル + 型チェックしてbabel-loaderでjsにコンパイルするのがいいのでしょうか?詳しい方いらっしゃったらご教示頂ければ幸いです。 

  2. 現状webpack v5系だとちょくちょくcliやdev-serverがエラー起こします。ググると大体バージョン落としたら治るパターンが多いです。  

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React入門 1週間でReactをマスターする #04. 条件分岐(if)と繰り返し(loop)

目次

1. Reactの新規プロジェクトの立ち上げ
2. コンポーネントの書き方とイベントハンドラ
3.Class Components と Function Components
4. 条件分岐 (if) と繰り返し (loop) ←今ここ
5. フォームと親子間のデータのやり取り (近日公開!)
6. コンポーネントのライフサイクル (準備中)
7. スタイル (準備中)
8. Higher-Order Component (準備中)
9. Portalを利用したモーダル (準備中)
10. refによるエレメントの取得 (準備中)
11. Contextを利用したテーマの変更 (準備中)

今回の学習内容

今回は、

  • JSX内での条件分岐(状態によっての表示切り替え)
  • JSX内での項目の繰り返し表示

をやっていきます。

YouTubeでの解説動画

YouTubeでも解説しています。
動画で確認したい方はこちらもどうぞ。
【YouTube動画】 未経験から1週間でをマスターするReact入門 #04. React入門 1週間でReactをマスターする #04. 条件分岐(if)と繰り返し(loop)
【YouTube動画】 未経験から1週間でをマスターするReact入門

この記事のソースコード

ソースコードはGitHubで公開しています。

https://github.com/yassun-youtube/ReactTutorial

今回は下記コミットをやっていきます。

スクリーンショット 2020-11-21 17.19.40.png

タブによる条件分岐

今回は、タブを作って、そのどのタブを表示しているかを状態で管理しておき、条件分岐をやってみます。

タブで List.jsForm.js の表示で入れ替えるようにしたいので、 Form.js を作成します。

src/Form.js
export const Form = () => {
  return (
    <div>
      フォームです
    </div>
  )
}

これを App.js に追加します。

src/App.js
import { useState } from 'react';
import { List } from "./List";
import { Form } from "./Form"; // 追加

function App() {
  const [description, setDescription] = useState('クリック前の表示');

  const changeDescription = () => {
    setDescription('クリック後の表示です。')
  }

  return (
    <div>
      { description }
      <List title="取り扱い言語一覧"/>
      <Form /> { /* 追加 */ }
      <button onClick={changeDescription}>ボタン</button>
    </div>
  );
}

export default App;

これで下図のように表示されます。

_2020-11-01_19.06.29.png

続いて App.js にヘッダ部分を追加します。

デザインをまだ当てていないのでタブのようには見えませんが、タブとして扱います。

src/App.js
import { useState } from 'react';
import { List } from "./List";
import { Form } from "./Form";

function App() {
  const [description, setDescription] = useState('クリック前の表示');

  const changeDescription = () => {
    setDescription('クリック後の表示です。')
  }

  return (
    <div>
      <header> { /* 追加 */ }
        <ul>
          <li>リスト</li>
          <li>フォーム</li>
        </ul>
      </header>
      <hr /> { // 追加 }
      { description }
      <List title="取り扱い言語一覧"/>
      <Form />
      <button onClick={changeDescription}>ボタン</button>
    </div>
  );
}

export default App;

これで下図のように表示されます。

_2020-11-01_19.08.49.png

この リスト フォーム というのをタブとみなして、 List.jsForm.js の表示の状態を管理するようにしてみましょう。

src/App.js
import { useState } from 'react';
import { List } from "./List";
import { Form } from "./Form";

function App() {
  const [description, setDescription] = useState('クリック前の表示');
  const [tab, setTab] = useState('list'); // 追加

  const changeDescription = () => {
    setDescription('クリック後の表示です。')
  }

  return (
    <div>
      <header>
        <ul>
          <li onClick={() => setTab('list')}>リスト</li>
          <li onClick={() => setTab('form')}>フォーム</li>
        </ul>
      </header>
      <hr />
      { description }
      { // 変更
        tab === 'list' ? <List title="取り扱い言語一覧"/> : <Form />
      }
      <button onClick={changeDescription}>ボタン</button>
    </div>
  );
}

export default App;

この変更で、ヘッダのリストの項目をクリックすることで内容が変わるようになりました。

84e768c41ffd00c2d42fe0d9a34fe715.gif

コード解説

コードの内容を見ていきましょう。

  const [tab, setTab] = useState('list'); // 追加

新しく、こちらのコードを追加しました。

これは、 tab という state を定義しています。 初期値は list です。

{ // 変更
  tab === 'list' ? <List title="取り扱い言語一覧"/> : <Form />
}

次にこちらの部分で表示を制御しています。

JSXでは、 {} は Javascript の値を入れられます。ここではその中で三項演算子を使って tab の状態で表示を分岐させていることがわかります。

Reactでは、このように条件分岐で画面の表示を変更することが可能です。

繰り返しによるリスト表示

次に、Reactによる繰り返しを見ていきます。

List.js に取り扱い言語のリストとなるステートを用意して、それをリスト表示させてみましょう。

src/List.js
const LANGUAGES = [ // 追加
  'JavaScript',
  'C++',
  'Ruby',
  'Java',
  'PHP',
  'Go'
];

export const List = ({ title }) => {
  return (
    <div>
      <h4>{ title }</h4>
      { // 変更
        LANGUAGES.map((lang, index) => {
          return <div key={index}>{ lang }</div>
        })
      }
    </div>
  )
}

いくつかコードを追加してみました。

こちらのコードにより、下図のように表示が変わります。

_2020-11-01_19.26.39.png

コード解説

const LANGUAGES = [ // 追加
  'JavaScript',
  'C++',
  'Ruby',
  'Java',
  'PHP',
  'Go'
];

まず、言語リストの初期値として定数を定義しています。

{
    LANGUAGES.map((lang, index) => {
      return <div key={index}>{ lang }</div>
    })
}

こちらのコードが繰り返しの部分です。

ここでは、 map 関数を使って <div> の配列を返しています。
Reactでは、繰り返しは基本的に map などの配列を返す関数を利用して行います。

繰り返しのTips
一つ注意しないといけないのは、繰り返しを行う際は、 繰り返される要素に key 属性を指定する必要があります。これは、Reactが繰り返された要素を区別するために必要なものなので、ユニークである必要があります。
無くても動きますが、コンソールにエラーが出ますし、予測不能なバグを生む可能性があるのでつけるようにしてください。

条件分岐、繰り返しまとめ

JSXでは、HTML(のようなもの)の中にコードが記載できるので、そこに 三項演算子や map などを利用して要素を返してやれば、条件分岐や繰り返しが可能になります。

JavaScriptを理解されている方なら、簡単に条件分岐や繰り返しが可能ですね。

次に向けた余計なコードの整理など

前回、 App.js 中で利用した descrption という state は、今後不要なので削除しておきます。

また、 titleList.jsprops として渡していますが、こちらも不要なので削除します。

src/App.js
import { useState } from 'react';
import { List } from "./List";
import { Form } from "./Form";

function App() {
  // descriptionを削除
  const [tab, setTab] = useState('list');

  return (
    <div>
      <header>
        <ul>
          <li onClick={() => setTab('list')}>リスト</li>
          <li onClick={() => setTab('form')}>フォーム</li>
        </ul>
      </header>
      <hr />
      { /* descriptionを削除 */ }
      {
        tab === 'list' ? <List /> : <Form /> // Listへのtitle属性を削除
      }
      { /* buttonを削除 */ }
    </div>
  );
}

export default App;

App.js から description に関連するコードと List.js への title 属性を削除しました。

次に、 List.js から title 属性を削除します。

List.js
const LANGUAGES = [
  'JavaScript',
  'C++',
  'Ruby',
  'Java',
  'PHP',
  'Go'
];

export const List = () => { // title を削除
  return (
    <div>
      { /* h4 を削除(title表示) */ }
      {
        LANGUAGES.map((lang, index) => {
          return <div key={index}>{ lang }</div>
        })
      }
    </div>
  )

これできれいになりました。

この状態で入門5に行きたいと思います。

今日やったこと

条件分岐による表示切り替え

条件分岐は、三項演算子を使うことで表現できました。

function Test() {
  return (
    <div>
      {
        tab === 'list' ? <List /> : <Form />
      }
    </div>
  )
}

こちらも可↓
letif を使って入れる値を変えるというやり方でもできます。

function Test() {
  const tabComponent = tab === 'list' ? <List /> : <Form />
  return (
    <div>
      { tabComponent }
    </div>
  )
}

繰り返しによるリスト表示

繰り返しは map 関数を使って表現しました。

function Test() {
  return (
    <div>
      {
        list.map((val, i) => {
          return <div key={i}>{ val }</div>
        })
      }
    </div>
  )
}

Class Componentsへの反映

ここからは、上記の内容を Class Componentsに適用していきます。

ブランチを class-components ブランチに切り替えて、 Class Components で今回の最終形の状態に持っていきます。

git checkout class-components

Class Componentsへの反映

src/App.js
import React from 'react';
import { List } from "./List";
import { Form } from "./Form";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { tab: 'list' };
  }
  render() {
    const { tab } = this.state;
    return (
      <div>
        <header>
          <ul>
            <li onClick={() => this.setState({ tab: 'list' })}>リスト</li>
            <li onClick={() => this.setState({ tab: 'form' })}>フォーム</li>
          </ul>
        </header>
        <hr />
        {
          tab === 'list' ? <List /> : <Form />
        }
      </div>
    )
  }
}

export default App;
src/List.js
import React from 'react';

const LANGUAGES = [
  'JavaScript',
  'C++',
  'Ruby',
  'Java',
  'PHP',
  'Go'
];

export class List extends React.Component {
  render() {
    return (
      <div>
        {
          LANGUAGES.map((lang, index) => {
            return <div key={index}>{ lang }</div>
          })
        }
      </div>
    )
  }
}
src/Form.js
import React from 'react';

export class Form extends React.Component {
  render() {
    return (
      <div>フォームです</div>
    )
  }
}

これでClass Component側にも反映できました。
同じことをClass Components側にもやることで、復習になります。

おわりに

今日は条件分岐と繰り返しについて学びました。

次は、フォームと親子間のデータのやり取りについてお話していきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【React,useMemo】今日の日付の計算でuseMemoを使用したら無駄な計算を減らせました。

useMemoの活用

useMemo使ったとき感動したので皆様に共有したくて書きました!

作成中のアプリ

筋トレの種類と、その筋トレを回数を記録するアプリ。
UIはこんな感じで、左上の入力フォームに筋トレの種類(腕立て、スクワットなど)を入力して送信すると、コンポーネントが追加されていくようになっています。
スクリーンショット 2020-11-21 12.33.06.png

未実装ですが、そのコンポーネントの中のフォームで日付と回数を入力して送信すると、その下に記録が溜まっていくイメージです。(UIはこれが最適かどうかはさておき...)

inputタグの初期値を本日の日付にしたいが再計算が多くなる...

筋トレ記録アプリの作成の中で、日付と筋トレ回数を入力するフォームを作成した。入力するタイミングとして当日中(筋トレ直後)に回数を記録することが多いと思われるため、日付の入力フォームの初期値を当日の日付にしたいと思ったのですが、普通に書くと再計算が多くなり無駄が発生してしまいました...

useMemo無し

useMemo無しだと、筋トレの種類を追加するたびに、別ディレクトリに書いたtoday.tsのcalculateToday関数が余計に実行されてしまいます。
スクリーンショット 2020-11-21 12.42.08.png

●コード

import React , { FC , useState,useMemo} from 'react';
import Training from '../organisms/training';
import { useForm } from 'react-hook-form';
import { calculateToday } from '../today/today';
import './trainingList.scss';

type training = {
    trainingName: string,
}

const TrainingList: FC = () => {
    const { register , handleSubmit , reset} = useForm<training>();   
    const [ trainingList, setList ] = useState<training[]>([]);
    // const today = useMemo(()=> calculateToday(),[])
    const today = calculateToday()

    const onSubmit = (data: training) => {
        const {trainingName} = data;
        if (!trainingName) {
            alert('トレーニング名を入力してください。') 
            return
        } else if (trainingList.some((name) => name.trainingName === trainingName )) { 
            alert("そのトレーニングは既に登録されています。") 
            reset()
            return
        }

        setList([
            ...trainingList,
            {trainingName:trainingName}   
        ]);

        reset();
    }

    return (
        <div className='container'>
                <form className='input-form' onSubmit={handleSubmit(onSubmit)}>
                    <input name='trainingName' ref={register} placeholder='training name'/>
                    <input type='submit'/>
                </form>

            <div className='main'>
                {
                    trainingList.map((list) => {
                        return(
                                <Training
                                    trainingName={list.trainingName}
                                    key={list.trainingName}
                                    today={today}
                                />
                        )
                    })
                }            

            </div>

        </div>
    )
}

export default TrainingList;

useMemoあり

useMemoを使用すると、calculateToday関数の実行を1回だけにすることができ、下記の検証ツールをご覧いただければ分かる通り、余計な再計算を無くすことができました。
スクリーンショット 2020-11-21 12.50.05.png

コードは上記コードのTrainingListコンポーネントの上から4行目のコードの代わりに、3行目のコメントアウトしている部分を復活させるだけです。

    const today = useMemo(()=> calculateToday(),[])
    // const today = calculateToday()

最後に

ここまで偉そうに書いてきましたが、業務未経験のため、そもそももっと良い実装方法、UIがあるかもしれませんが、useMemoの活用例の1例として皆様に共有できればと思いました!ご指摘等、厳しい意見お待ちしております!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

create-react-app でtypescriptテンプレート指定した場合の対処法

最新のcreate-react-appでtypescriptを指定した場合、下記エラーが発生するため私がとった対応策です

npx create-react-app <プロジェクト名> --template typescript
でプロジェクト作成後 npm start すると下記エラー↓

TypeError: Cannot assign to read only property 'jsx' of object ''
*エラー文以下省略

対応策
①srcフォルダ内にあるpackage.jsonのreact-scriptsとtypescriptのバージョンを下記内容に書き換える。
"react-scripts": "4.0.0-next.98",
"typescript": "^4.1.0",

②VS codeのターミナルで下記コマンド実行
rm -rf node_modules package-lock.json && npm i

③npm start

私はこれで対処できました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

create-react-app typescriptテンプレート指定時エラーの対処法

最新のcreate-react-appでtypescriptを指定した場合、下記エラーが発生するため私がとった対応策です

npx create-react-app <プロジェクト名> --template typescript
でプロジェクト作成後 npm start すると下記エラー↓

TypeError: Cannot assign to read only property 'jsx' of object ''
*エラー文以下省略

対応策
①srcフォルダ内にあるpackage.jsonのreact-scriptsとtypescriptのバージョンを下記内容に書き換える。
"react-scripts": "4.0.0-next.98",
"typescript": "^4.1.0",

②node_modules & package-lock.jsonを削除

③npm install

④npm start

私はこれで対処できました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む