React.jsの頻繁な問題

こんにちは、Habr! Samer Bunaの記事「React.jsのよくある問題」の翻訳を紹介します。

パニックにならないでください。 あなたは正しいです。無数のWebテクノロジー、アーキテクチャ、フレームワークがあり、現在多くが開発されています。 覚えておいてください:プロのウェブ開発者になった人はみなあなたのように始めました。 彼らは自分たちのスキルと動作メカニズムを活気付けるまで、言語、図書館を次々と勉強しました



Web開発は現在、スーパーマーケットへの最初の旅行です。 棚には何百もの商品があります。 混乱して、膨大な選択を恐れることは非常に簡単です。 どこでも有能である必要があるかのように、一度にすべてを研究しようとするのは間違いです。



実際、たとえば、ライブラリのない最も単純なHTML / CSS / JavaScriptを使用してWebサイトを作成し、Reactのようなフレームワークを追加するなど、1つのことに集中すると、初心者から専門家への道がはるかに便利で快適になります。

実際、経験豊富な開発者が注意を払っていない単純なことを初心者が扱うのは難しい場合があります。 この記事は、ほとんどのReact学習者が遭遇する一般的な間違いや困難に対処することを目的としています。



1-小文字のコンポーネント名



Reactコンポーネントには大文字の名前が必要です。 そうでない場合、コンポーネントは組み込みのdivまたはspanとして処理されます



例:



class greeting extends React.Component { // ... }
      
      





フレームワークを渡す(レンダリング)<greeting />-Reactはエラーをスローします:



 Warning: The tag <greeting> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.
      
      





「大文字から始めてください、難しいですか?」



*また、 ボタンコンポーネント、 img 、およびその他のタグを呼び出さないでください。 Reactは単にそれらを無視し、裸のHTMLタグとしてレンダリングします。



画像



2-アポストロフィをバックスライドする代わりに単一引用符を使用する



文字列は逆アポストロフィ`...` )(元の「バックティック」)で作成され、通常の単一引用符( '...' )とは異なります。



ほとんどのキーボードでは、タブの上にあるキーを押すことで逆アポストロフィを設定できます。



改行や後続の連結を使用せずに動的式を文字列に挿入する必要がある場合に使用します。



 `         ` '     '
      
      





状況を想像してみましょう。「時間:...」の時間に関するメッセージを表示する必要があります



 //       const time = new Date().toLocaleTimeString(); //    ,  //    'Time is ' + time //    ,  //    ${} `Time is ${time}`
      
      





また、逆アポストロフィの内側で改行を行うことができます。



 const template = `      `;
      
      





通常の単一引用符では、これを行いません。



3-React.PropTypesの使用



PropTypesオブジェクトはReactから削除されました。 単に存在しないので、それに慣れる必要があります。 しかし今:





今では動作します。 例: PropTypes.string



コードにまだReact.PropTypesの行がある場合、エラーが発生します

頭の上に:



 TypeError: Cannot read property 'string' of undefined
      
      





4-チュートリアルで説明されているバージョンを使用する



プログラミングレッスンを表示したり読んだり、そこから例を参照するときは、レッスンに適したバージョンを使用していることを確認してください。 通常、モジュールの最新バージョンを使用しても安全ですが、チュートリアルは古くなっています。 その結果、間違いなくエラーが発生します。 逆に、チュートリアルでReact 16を使用している場合、15番目のバージョンを置き換えるのを怠らないでください。



これはNode.jsにとって特に重要です。 すべてのコーナーに古いバージョンのエラーがあります。 たとえば、 ノード7.xではObject.valuesが削除されたため、ノード6.xでコードを修正するよりも簡単にアップグレードできます。



5-関数とクラスの混乱



このコードのどこにエラーがあるのか​​わかりますか?



 class Numbers extends React.Component { const arrayOfNumbers = _.range(1, 10); // ... }
      
      





JavaScriptクラスの本体内には、 実質的に何にも権利がないため、コードは正しくありません。 メソッドとプロパティは、限られた構文を介してのみ宣言できます。



クラス構文内の{}中括弧は見慣れたブロック構造のように見えますが、そうではないので、これは本当に紛らわしいです。



アクションの自由が必要な場合は、機能に基づいたコンポーネントを使用します。



 const Number = (props) => { const arrayOfNumbers = _.range(1, 10); // ... };
      
      





6-文字列としての数字



文字列を使用してプロパティを渡すことができます:



 <Greeting name="World" />
      
      





番号を渡す必要がある場合は、引用符でそれらを書き込まないでください。



 //   ! <Greeting counter="7" />
      
      





代わりに、それらを中括弧に挿入します。



 <Greeting counter={7} />
      
      





Greetingコンポーネント内で{7}を使用すると、 this.props.counterを使用して番号を取得できます。これを使用して数学演算を実行することは絶対に安全です。 「7」を誤って使用すると、予測できない結果を招く可能性があります。



7-1つのポートで2つのアプリケーション



Webサーバーを起動するには、 ホスト (127.0.0.1など)とポート (8080など)が必要で、サーバーが正しいhttpアドレスで要求をリッスンするように強制します。



サーバーが起動するとすぐに、ポートを完全に制御できます。 同じポートでアイロンをオンにすることはできなくなります。 彼は忙しくなります(鉄ではなく港です!)。



別の端末から同じサーバーを起動してみてください。 ほとんどの場合、「使用済み」エラーが表示されます。



 Error: listen EADDRINUSE 127.0.0.1:8080
      
      





ポートがバックグラウンドで使用されていることが判明する場合があります 。 あなたは彼を見ませんが、彼は人生を妨げます。 そのような状況では、貴重なポートを占有しているポートを「殺す」ことは有益です。



 lsof -i :8080
      
      





8-環境変数



一部のプロジェクトは、 環境変数の存在に依存しています (「環境変数」)。 必要な変数なしでアプリケーションを実行すると、 未定義の値( undefined )の使用を開始しようとします。もちろん、これは重大なエラーにつながります。



たとえば、プロジェクトがMongoDBデータベースに接続されている場合、 process.env.Mongo_URIなどの環境変数は、データベースに安全に接続するのに役立ちます。 また、状況に応じてすばやく変更することもできます(別のデータベースに接続する必要はありません)。



MongoDBでプロジェクトをローカルで実行するには、最初にMONGO_URI変数をエクスポートする必要があります。 必須、たとえばデータベースがポート27017で機能する場合、アプリケーションを起動する前にこれを実行します。



 export MONGO_URI = "mongodb://localhost:27017/mydb"
      
      





9-カーリー{}または括弧()



代わりに



 return { something(); };
      
      





書きます



 return ( something(); );
      
      





最初の例ではオブジェクトを返そうとしますが(失敗します)、2番目の例ではsomething()関数を呼び出して、関数が返すべきものを返すことができます。



JSX構文の<tag>は関数を呼び出すため、この問題はすべてのJSXコードに適用されます。



矢印関数にも使用できます (「矢印関数」)。 代わりに



 const Greeting = () => { <div> Hello World </div> };
      
      





書きます



 const Greeting = () => ( <div> Hello World </div> );
      
      





*覚えておいてください:ES6では矢印関数の中括弧は不要です!*



10-オブジェクトを括弧で囲まないでください



前の段落のトピックを終了します。 通常のオブジェクトを返すために矢印関数を参照することで混乱しやすくなります。



代わりに



 const myAction = () => { type: 'DO_IT' };
      
      





書きます



 const myAction = () => ({ type: 'DO_IT'});
      
      





オブジェクトを括弧で囲むことなく、短い構文の目的を達成することはできません。



統合するには、同様の既製の例を考えてみましょう。



 this.setState(prevState => ({ answer: 12 }));
      
      





11-メソッドで間違った文字を使用する



React.Componentであり、 React.componentではありませComponentDidMountではなくcomponentDidMountです。 実際にはReactDOMですがReactDomではありませ



さまざまな方法がどのように書かれているかに注意してください。そのような間違いを犯すと、あなたは本当に多くの時間を費やすことができ、あなたは自分自身を恥ずかしく思うでしょう。 ESLintを試してください。このようなエラーを追跡するのに役立ちます。



多くの場合、プロパティにアクセスするとエラーが発生します。



 <Greeting userName="Max" /> //   props.userName
      
      





たとえば、 props.userNameの代わりにprops.usernameまたはprops.UserName 入力すると、値undefinedが返されます。



12-状態オブジェクトのアプリケーションのエラー



クラスコンポーネントでは、ローカル状態オブジェクトを宣言し、後でこれを介して値を取得できます。



 class Greeting extends React.Component { state = { name: "", }; render() { return `, ${this.state.name}` } }
      
      





プログラムは“, ”



を表示します。



状態の代わりに、オブジェクトの任意の名前を使用できます。 例:



 class Greeting extends React.Component { user = { name: "", }; render() { return `, ${this.user.name}` } }
      
      





同じものを印刷します。



ただし、違いがあります。 状態は、Reactによって制御される特別なオブジェクトです。 setStateを介して値を変更でき、React これに応答します。 このようなトリックは上記のサンプルコードでは機能しませんが、反応を見たくない場合でも使用できます。



13-<tag />および</ tag>のポリッジ



タグを閉じるときは、 スラッシュ /を付けることを忘れないでください。 はい、場合によっては<tag />が必要なこともあれば、 </ tag>が必要な場合もあります。



HTMLには自己終了タグがあります (「自己終了タグ」)。 これらは「子供」のいない要素です。 たとえば、 imgはこれらを指します。



 <img src="..." /> //    <img></img>
      
      





divタグには好きなだけ他のタグを添付できるので、開いたり閉じたりする必要があります。



 <div>  ... </div>
      
      





同じルールがReactコンポーネントに適用されます。



 <Greeting>Hello!</Greeting> //  ,   
      
      





ただし、「子供」がいない場合でも、それを開いたり閉じたりできます。また、自己終了タグを使用することもできます。



 // 2   <Greeting></Greeting> <Greeting />
      
      





誤ったアプリケーションの例:



 //    <Greeting><Greeting />
      
      





そこからエラーが表示されるはずです:



 Syntax error: Unterminated JSX contents
      
      





14-インポート/エクスポートは「正しく機能する」という期待



インポート/エクスポート機能は、2015年からJavaScriptによって公式にサポートされています 。 ただし、これはすべてのブラウザーとNodeの最新バージョンで完全にサポートされていないES2015からの唯一のものです。



多くの場合、ReactプロジェクトはWebpackとBabelで作成されます。 すべてのブラウザが理解できるものにコードをコンパイルできます。 したがって、 WebpackおよびBabelでインポート/エクスポートを使用することをお勧めします。



Nodeにインポート/エクスポートを理解させるために、たとえば、フロント(フロントエンド)で使用し、 SSRサーバー側レンダリング-サーバーでのレンダリング、同形アプリケーション )を使用する場合に、これが必要になることがあります 。 これを行うには、Node自体にBabelが存在する必要があります。 開発の便宜上、 pm2nodemonbabel-watchから何かを接続することをお勧めします。



15-バインドの問題



Reactコンポーネントでクラスメソッドを宣言し、renderメソッドに含めることができます。 例:
 class Greeting extends React.Component { whoIsThis() { console.dir(this); // "this"   whoIsThis return "World" } render() { return `Hello ${this.whoIsThis()}` } } ReactDOM.render(<Greeting />, mountNode);
      
      





render 。の内部でwhoIsThisメソッドをthis.whoIsThisを使用して使用しました。この場合、 これはDOM要素(コンポーネント自体)にアクセスするためです。



Reactはこれを確認しようとしています。 ただし、JavaScriptはthisメソッドとwhoIsThisメソッドを自動的にバインド(元の「バインド」)しようともしません。



これを例でテストします。 メソッドはrenderから直接呼び出されたため、whoIsThisのconsole.dir行はGreetingオブジェクトを出力します。



画像



ただし、すぐに呼び出されない場所、たとえばイベントハンドラー (元の「イベントハンドラー」)でクラスメソッドを使用すると、 console.dirは予期したものを出力しません。



画像



上記の例では、React は行をクリックした後にのみwhoIsThisメソッドを呼び出します。これにより、内部からコンポーネントにアクセスできなくなります。 それがあなたが未定義になる理由です。



これは、クラスメソッドからthis.propsまたはthis.stateを取得しようとするときに問題が発生することが多い序文です。 うまくいきません。 これを解決する方法はたくさんあります。 メソッドを関数でラップするか、 .bindを使用して、メソッドに呼び出し元を記憶させることができます。 また、 renderではなく、クラスコンストラクターで バインドすることもできます



それでも、最良の解決策は、 Babelを介してクラスにECMAScript (これはstage-3です )の機能を使用し、ハンドラーに矢印関数を記述することです。



 class Greeting extends React.Component { whoIsThis = () => { console.dir(this); } render() { return ( <div onClick={this.whoIsThis}> Hello World </div> ); } }
      
      





これは期待どおりに機能します。



画像



以上です。 読んでくれてありがとう。



All Articles