ホームページ >ウェブフロントエンド >jsチュートリアル >Reactフック:あなた自身を始めて構築する方法

Reactフック:あなた自身を始めて構築する方法

Joseph Gordon-Levitt
Joseph Gordon-Levittオリジナル
2025-02-10 10:48:091002ブラウズ

Reactフック:あなた自身を始めて構築する方法

フックは反応の世界を席巻しています。このチュートリアルでは、フックとは何か、どのように使用するかを見ていきます。 Reactで出荷するいくつかの一般的なフックを紹介し、自分のものを書く方法を示します。終了する頃には、自分のReactプロジェクトでフックを使用できるようになります。

キーテイクアウト

    Reactフックの簡素化コンポーネントロジック:フックを使用すると、クラスなしで状態やその他の反応機能を使用でき、コードをクリーンにして理解しやすくします。
  • useState and useEffectは基本的です。「useState」では、機能コンポーネントに状態を追加できます。一方、「effect」は以前に「componentdidmount」や「componentdidupdate」などのライフサイクルメソッドで管理されていた副作用を処理できます。
  • カスタムフックは再利用可能性を向上させます:独自のフックを作成してコンポーネントロジックを再利用可能な関数に抽出し、コードベースをより乾燥させます(繰り返さないでください)。
  • フックは複数の状態と効果をサポートしています。単一のコンポーネントで複数の「UseState」および「UseEffect」インスタンスを使用して、さまざまな状態とさまざまな効果を管理できます。
  • サードパーティフックの拡張機能:サードパーティライブラリからのフックを使用すると、「axios-hook」でデータを取得するなど、追加の機能を効率的に導入できます。
  • クラスから機能コンポーネントへの移行:フックの導入は、既存のクラスベースのコンポーネントを機能的なコンポーネントにリファクタリングする強力なインセンティブを提供し、読みやすさと保守性の向上を活用します。
  • 反応フックとは?
  • Reactフックは、関数コンポーネントの反応機能を「フック」できる特別な機能です。たとえば、UseStateフックを使用すると状態を追加できますが、Effectを使用すると副作用を実行できます。以前は、ライフサイクル方法を使用して副作用が実装されていました。フックでは、これはもはや必要ありません。
  • これは、Reactコンポーネントを構築するときにクラスを定義する必要がなくなったことを意味します。 Reactで使用されるクラスアーキテクチャは、React開発者が毎日直面する多くの課題の原因であることがわかります。私たちはしばしば、分裂が難しい、大きくて複雑なコンポーネントを書いていることに気づきます。関連するコードは、いくつかのライフサイクル方法に広がっています。これは、読み、維持、テストが難しくなります。さらに、状態、小道具、方法にアクセスする際には、このキーワードに対処する必要があります。また、コンポーネント内でアクセスできるように、これにメソッドをバインドする必要があります。それから、高次コンポーネントを扱うとき、私たちは過剰な小道具掘削の問題 - ラッパー・ヘルとも呼ばれます。一言で言えば、フックはコードを簡素化し、読みやすく、維持し、分離してテストし、プロジェクトで再利用できるようにする革新的な機能です。それらに精通するのに1時間しかかかりませんが、これにより、Reactコードの書き方について違った考え方をします。

    Reactフックは、2018年10月に開催されたReact Conferenceで最初に発表され、React 16.8で公式に利用可能になりました。機能はまだ開発中です。まだ多くのReactクラス機能がフックに移行されています。良いニュースは、今すぐ使用を開始できることです。必要に応じてReactクラスコンポーネントを使用することもできますが、この入門ガイドを読んだ後にしたいと思うとは思いません。

    私があなたの好奇心をそそりたなら、飛び込み、いくつかの実用的な例を見てみましょう。

    前提条件

    このチュートリアルは、反応が何であり、どのように機能するかを基本的に理解している人々を対象としています。 React初心者の場合は、ここで進む前にReactチュートリアルを始めましょう。

    例をフォローしたい場合は、Reactアプリが既にセットアップされている必要があります。これを行う最も簡単な方法は、Create Reactアプリツールを使用することです。これを使用するには、ノードとNPMがインストールされます。そうでない場合は、node.jsダウンロードページにアクセスして、システムの最新バージョンをつかみます(NPMにはノードがバンドルされています)。または、バージョンマネージャーを使用してノードのインストールについてチュートリアルを参照してください。

    ノードがインストールされていると、次のような新しいReactアプリを作成できます。

    これにより、MyAppフォルダーが作成されます。このフォルダーに変更して、そのように開発サーバーを起動します:

    デフォルトのブラウザが開き、新しいReactアプリが表示されます。このチュートリアルの目的のために、src/app.js。

    にあるアプリコンポーネントで作業することができます。
    npx create-react-app myapp
    
    このチュートリアルのこのチュートリアルのコードと、このチュートリアルの最後にある完成したコードのデモも見つけることができます。

    uesestate hook

    <span>cd myapp
    </span><span>npm start
    </span>
    次に、いくつかのコードを見てみましょう。 UseStateフックは、おそらくReactに出荷される最も一般的なフックです。名前が示すように、関数コンポーネントで状態を使用できます。

    次のReactクラスコンポーネントを検討してください:

    Create Reactアプリをフォローしている場合は、app.jsの内容を上記に置き換えてください。

    これが見た目です:

    コードを理解するために少し時間を与えてください。 コンストラクターでは、状態オブジェクトの名前プロパティを宣言し、コンポーネントインスタンスにハンドレンマンガンジ関数をバインドしています。次に、入力のあるフォームがあり、その値はthis.state.nameに設定されています。 this.state.nameに保持されている値は、挨拶の形でページに出力されます。

    ユーザーが入力フィールドに何かを入力すると、HandlenAmechange関数が呼び出され、状態とその結果、挨拶を更新します。

    次に、UseState Hookを使用してこのコードの新しいバージョンを作成します。その構文は次のようになります:

    npx create-react-app myapp
    
    useState関数を呼び出すと、2つの項目が返されます。

    状態:あなたの状態の名前 - this.state.nameまたはthis.state.locationなどのような。
      SetState:状態に新しい値を設定するための関数。 this.setState({name:newValue})。
    • に似ています
    • 初期標準は、州の宣言段階で新たに宣言された状態に与えるデフォルト値です。 UseStateが何であるかについてのアイデアができたので、それを実行しましょう。
    この関数バージョンとクラスバージョンの違いに注意してください。すでにクラスバージョンよりもはるかにコンパクトで理解しやすいですが、どちらもまったく同じことをしています。違いを見てみましょう:

    <span>cd myapp
    </span><span>npm start
    </span>
    クラス全体のコンストラクターは、単一の行で構成されるUseStateフックに置き換えられました。

    UseStateフックはローカル変数を出力するため、このキーワードを使用して関数変数または状態変数を参照する必要はなくなりました。正直なところ、これはほとんどのJavaScript開発者にとって大きな痛みです。これを使用する必要があるとは限らないためです。

    JSXコードは、これを使用せずにローカルの状態値を参照できるため、クリーンになりました。
    • 今までに感銘を受けたことを願っています!複数の状態値を宣言する必要がある場合、何をすべきか疑問に思うかもしれません。答えは非常に簡単です。別のユーザーフックを呼び出すだけです。コンポーネントを過度に統合していない場合、何度も宣言できます。
    • 注:Reactフックを使用する場合、コンポーネントの上部にそれらを宣言して、条件付きではないようにしてください。
    • 複数のueseStateフック
    しかし、州内で複数のプロパティを宣言したい場合はどうなりますか?問題ない。 useStateに複数の呼び出しを使用してください。

    ここに複数のuseStateフックがあるコンポーネントの例があります:

    非常に簡単ですね。クラスバージョンで同じことをするには、このキーワードをさらに使用する必要があります。

    さあ、次の基本的なReactフックに進みましょう。

    Effect hookを使用してください

    データの取得、データストリームへのサブスクライブ、または手動でDOMの変更などの特定の操作を実行するには、ほとんどのReactコンポーネントが必要です。これらの種類の操作は、副作用として知られています

    クラスベースのコンポーネントでは、通常、副作用コードをComponentDidMountとcomponentDidupdateに入れます。これらは、適切なタイミングでレンダリング方法をトリガーできるライフサイクル方法です。

    ここに簡単な例があります:
    <span>import <span>React</span> from "react";
    </span>
    <span>export default class ClassDemo extends React<span>.Component</span> {
    </span>  <span>constructor(props) {
    </span>    <span>super(props);
    </span>    <span>this.state = {
    </span>      <span>name: "Agata"
    </span>    <span>};
    </span>    <span>this.handleNameChange = this.handleNameChange.bind(this);
    </span>  <span>}
    </span>
      <span>handleNameChange(e) {
    </span>    <span>this.setState({
    </span>      <span>name: e.target.value
    </span>    <span>});
    </span>  <span>}
    </span>
      <span>render() {
    </span>    <span>return (
    </span>      <span><section>
    </span>        <span><form autoComplete="off">
    </span>          <span><section>
    </span>            <span><label htmlFor="name">Name</label>
    </span>            <span><input
    </span>              type<span>="text"
    </span>              name<span>="name"
    </span>              id<span>="name"
    </span>              value<span>={this.state.name}
    </span>              onChange<span>={this.handleNameChange}
    </span>            <span>/>
    </span>          <span></section>
    </span>        <span></form>
    </span>        <span><p>Hello {this.state.name}</p>
    </span>      <span></section>
    </span>    <span>);
    </span>  <span>}
    </span><span>}
    </span>
    npx create-react-app myapp
    

    このコードは、州で保持されているものに基づいてドキュメントタイトルを設定します。ただし、フォームを介して状態値に変更を加えると、何も起こりません。これを修正するには、別のライフサイクル方法を追加する必要があります。

    フォームの更新もドキュメントタイトルを更新する必要があります。
    <span>cd myapp
    </span><span>npm start
    </span>
    Useefectフックを使用して同じロジックを実装する方法を見てみましょう。上記の関数コンポーネントを次のように更新してください:

    これらの数行のコードだけで、1つの単純な関数に2つのライフサイクルメソッドの作業を実装しました。

    <span>import <span>React</span> from "react";
    </span>
    <span>export default class ClassDemo extends React<span>.Component</span> {
    </span>  <span>constructor(props) {
    </span>    <span>super(props);
    </span>    <span>this.state = {
    </span>      <span>name: "Agata"
    </span>    <span>};
    </span>    <span>this.handleNameChange = this.handleNameChange.bind(this);
    </span>  <span>}
    </span>
      <span>handleNameChange(e) {
    </span>    <span>this.setState({
    </span>      <span>name: e.target.value
    </span>    <span>});
    </span>  <span>}
    </span>
      <span>render() {
    </span>    <span>return (
    </span>      <span><section>
    </span>        <span><form autoComplete="off">
    </span>          <span><section>
    </span>            <span><label htmlFor="name">Name</label>
    </span>            <span><input
    </span>              type<span>="text"
    </span>              name<span>="name"
    </span>              id<span>="name"
    </span>              value<span>={this.state.name}
    </span>              onChange<span>={this.handleNameChange}
    </span>            <span>/>
    </span>          <span></section>
    </span>        <span></form>
    </span>        <span><p>Hello {this.state.name}</p>
    </span>      <span></section>
    </span>    <span>);
    </span>  <span>}
    </span><span>}
    </span>

    クリーンアップコードの追加

    Reactフック:あなた自身を始めて構築する方法これは簡単な例でした。ただし、データストリームからの登録解除やイベントリスナーからの登録解除など、クリーンアップコードを作成する必要がある場合があります。これが通常、Reactクラスコンポーネントにどのように実装されているかの例を見てみましょう:

    上記のコードには、ブラウザウィンドウの現在の解像度が表示されます。ウィンドウのサイズを変更すると、数字が自動的に更新されることが表示されます。 Chromeで

    f11

    を押すと、モニターの完全な解像度を表示する必要があります。また、ライフサイクルメソッドComponentWillunMountを使用して、サイズ変更イベントの登録を解除しました。
    <span>const [state, setState] = useState(initialState);
    </span>
    フックバージョンの上記のクラスベースのコードを複製しましょう。この新しい機能を処理するには、3番目のUseStateフックと2番目の使用Effectフックを定義する必要があります。

    驚くべきことに、このコードのフックバージョンはまったく正確に行われます。よりクリーンでコンパクトです。コードを独自の使用効果宣言に入れることの利点は、コードが単独であるため、簡単にテストできることです。

    このUseefectフックで関数を返していることに気づきましたか?これは、Useefect関数内で返す関数がクリーンアップのコードと見なされるためです。関数を返さない場合、クリーンアップは実行されません。この場合、クリーンアップが必要です。それ以外の場合は、「マウントされていないコンポーネントでReact State Updateを実行できない」というブラウザコンソールにログインしたエラーメッセージが発生します。
    <span>import <span>React, { useState }</span> from "react";
    </span>
    <span>export default function <span>HookDemo</span>(props) {
    </span>  <span>const [name, setName] = useState("Agata");
    </span>
      <span>function handleNameChange(e) {
    </span>    <span>setName(e.target.value);
    </span>  <span>}
    </span>
      <span>return (
    </span>    <span><section>
    </span>      <span><form autoComplete="off">
    </span>        <span><section>
    </span>          <span><label htmlFor="name">Name</label>
    </span>          <span><input
    </span>            type<span>="text"
    </span>            name<span>="name"
    </span>            id<span>="name"
    </span>            value<span>={name}
    </span>            onChange<span>={handleNameChange}
    </span>          <span>/>
    </span>        <span></section>
    </span>      <span></form>
    </span>      <span><p>Hello {name}</p>
    </span>    <span></section>
    </span>  <span>);
    </span><span>}
    </span>
    カスタム反応フック

    Reactフック:あなた自身を始めて構築する方法 UseStateとEffect Hooksについて学んだので、これまでに達成したよりもコードをさらにコンパクトでクリーンで再利用可能にするための本当にクールな方法を見せてください。コードをさらに簡素化するために、

    カスタムフック

    を作成します。

    これを行い、サイズの機能を抽出し、コンポーネントの外側に配置します。

    次のように新しい関数を作成します:

    次に、コンポーネントでは、このコードを置き換える必要があります。

    …これで:

    2番目の使用Effectコードを削除します。ファイルを保存してテストします。すべてが以前と同じように機能するはずです。

    最初のカスタムフックを作成したので、ドキュメントタイトルについても同じことをしましょう。まず、コンポーネント内でEffectを使用するために残りの呼び出しを削除します。次に、コンポーネントの外側に、次のコードを追加します

    npx create-react-app myapp
    
    最後に、コンポーネント内から呼び出してください:

    <span>cd myapp
    </span><span>npm start
    </span>
    ブラウザに戻り、入力フィールドに何かを入力します。ドキュメントのタイトルは、前と同じように変更する必要があります

    最後に、フォームフィールドをリファクタリングしましょう。私たちは、州の対応する値と同期するためのフックを作成したいと考えています。

    カスタムフックから始めましょう。コンポーネントの外側に次のものを追加します:

    次に、コンポーネントを更新して使用します

    <span>import <span>React</span> from "react";
    </span>
    <span>export default class ClassDemo extends React<span>.Component</span> {
    </span>  <span>constructor(props) {
    </span>    <span>super(props);
    </span>    <span>this.state = {
    </span>      <span>name: "Agata"
    </span>    <span>};
    </span>    <span>this.handleNameChange = this.handleNameChange.bind(this);
    </span>  <span>}
    </span>
      <span>handleNameChange(e) {
    </span>    <span>this.setState({
    </span>      <span>name: e.target.value
    </span>    <span>});
    </span>  <span>}
    </span>
      <span>render() {
    </span>    <span>return (
    </span>      <span><section>
    </span>        <span><form autoComplete="off">
    </span>          <span><section>
    </span>            <span><label htmlFor="name">Name</label>
    </span>            <span><input
    </span>              type<span>="text"
    </span>              name<span>="name"
    </span>              id<span>="name"
    </span>              value<span>={this.state.name}
    </span>              onChange<span>={this.handleNameChange}
    </span>            <span>/>
    </span>          <span></section>
    </span>        <span></form>
    </span>        <span><p>Hello {this.state.name}</p>
    </span>      <span></section>
    </span>    <span>);
    </span>  <span>}
    </span><span>}
    </span>
    コードをゆっくりと通過し、行ったすべての変更を特定します。かなりきれいですよね?私たちのコンポーネントははるかにコンパクトです。

    このチュートリアルの目的のために、私たちはそれらを使用するコンポーネントと同じファイル内の機能としてフックを宣言しています。ただし、通常のReactプロジェクトでは、これらの各フックが別のファイルにあるフックフォルダーがあり、必要な場所にインポートできます。

    コードの主なロジックとは完全に独立しているため、useforminput、usewindowresolutionフックを外部NPMモジュールにパッケージ化することもできます。これらのカスタムフックは、プロジェクトの他の部分、または将来の他のプロジェクトでも簡単に再利用できます。 参照のために、完全なHooksコンポーネントバージョン:
    <span>const [state, setState] = useState(initialState);
    </span>
    を参照してください

    フックのコンポーネントは、クラスコンポーネントバージョンとまったく同じようにレンダリングして動作する必要があります。

    フックバージョンをクラスコンポーネントバージョンと比較すると、フック機能によりコンポーネントコードが少なくとも30%削減されることがわかります。再利用可能な機能をNPMライブラリにエクスポートすることで、コードをさらに削減することもできます。

    次に、コードで他の人のフックをどのように使用できるかを見てみましょう。

    サードパーティのフックを使用してデータを取得します
    <span>import <span>React, { useState }</span> from "react";
    </span>
    <span>export default function <span>HookDemo</span>(props) {
    </span>  <span>const [name, setName] = useState("Agata");
    </span>
      <span>function handleNameChange(e) {
    </span>    <span>setName(e.target.value);
    </span>  <span>}
    </span>
      <span>return (
    </span>    <span><section>
    </span>      <span><form autoComplete="off">
    </span>        <span><section>
    </span>          <span><label htmlFor="name">Name</label>
    </span>          <span><input
    </span>            type<span>="text"
    </span>            name<span>="name"
    </span>            id<span>="name"
    </span>            value<span>={name}
    </span>            onChange<span>={handleNameChange}
    </span>          <span>/>
    </span>        <span></section>
    </span>      <span></form>
    </span>      <span><p>Hello {name}</p>
    </span>    <span></section>
    </span>  <span>);
    </span><span>}
    </span>

    axiosとReactフックを使用して、REST JSON APIからデータを取得する方法の例を見てみましょう。自宅でフォローしている場合は、Axiosライブラリをインストールする必要があります。

    Reactフック:あなた自身を始めて構築する方法コンポーネントを変更して、次のようになります

    次の出力を期待する必要があります

    UseStateとEffectフックを使用する必要がなくなるように、独自のカスタムフックを構築することにより、上記のコードをリファクタリングすることができます。幸いなことに、多くの開発者はすでにこのクエストを満たしており、プロジェクトにインストールできるパッケージとしての仕事を公開しています。 Simone BusoliのAxios-Hooksを使用します。これは、たまたま最も人気のあるものです。

    コマンドを使用してパッケージをインストールできます:

    npx create-react-app myapp
    

    以下では、axios-hooks:

    を使用して上記のコードをリファクタリングしました
    <span>cd myapp
    </span><span>npm start
    </span>

    コードからUseStateと使用Effectフックを取り除いただけでなく、私たちの側に余分な脳力を持たずに3つの新しい能力を獲得しました。

    読み込みステータスを表示する
    • エラーメッセージを表示する
    • ボタンをクリックしてデータを返します
    ここでのレッスンは、ホイールの再発明を避けるためです。グーグルはあなたの友達です。 JavaScriptの世界では、誰かがあなたが取り組もうとしている問題をすでに解決している可能性が高いです。

    demo

    以下は、これまでに達成したことのライブデモです:

    これらは、日々の反応プロジェクトで出くわす基本的な反応フックです:

    uesestate:ローカル州の管理

      Effectの使用:ライフサイクル関数を置き換えます
    • USECONTEXT:React Context API(プロップ掘削の問題を解決する)を簡単に操作できるようになります また、プロジェクトの要件に応じて、使用する必要がある可能性のある追加の公式Reactフックもあります。
  • usereducer:複雑な状態ロジックを管理するためのUseStateの高度なバージョン。 Reduxと非常によく似ています
  • usecallback:キャッシュ可能な値を返す関数を返します。入力が変更されていないときに不必要な再レンダーを防ぐ場合は、パフォーマンスの最適化に役立ちます。
usememo:メモ化された関数から値を返します。 Vueに精通している場合は、計算に似ています

useref:コンポーネントの寿命のために持続する可変refオブジェクトを返します。

    ImperativeHandle:ref。
  • を使用するときに親コンポーネントに公開されるインスタンス値をカスタマイズします。
  • uselayouteffect:effectと同様ですが、すべてのdom変異の後に同期して発射します。
  • UsedeBugValue:React Developer Toolsにカスタムフック用のラベルを表示します。
  • 公式のReactドキュメントでこれらのフックについてすべてを読むことができます。
  • 要約
  • Reactコミュニティは、新しいReactフック機能に積極的に応答しました。 Awesome-Reacthooksと呼ばれるオープンソースリポジトリがすでにあり、このリポジトリに何百ものカスタムReactフックが提出されています。ローカルストレージに値を保存するためのフックの1つの簡単な例を次に示します。
npx create-react-app myapp

このようなnpmまたはyarnを使用してローカルストレージフックをインストールする必要があります。

<span>cd myapp
</span><span>npm start
</span>
かなりきちんとして、

Reactフックの導入により、大きなスプラッシュができました。その波は、Reactコミュニティを越えてJavaScriptの世界に移動しました。これは、フックがJavaScriptエコシステム全体に利益をもたらす新しい概念であるためです。実際、Vue.JSチームは最近、Composition APIと呼ばれる類似のものをリリースしました。

React HooksとContext APIが州の管理王座からのReduxを転覆することについての話もあります。明らかに、フックはコーディングをはるかに簡単にし、新しいコードの書き方を変えました。あなたが私のような場合、あなたはおそらくあなたのすべてのReactコンポーネントクラスを書き直し、それらを機能的なコンポーネントフックに置き換える強い衝動を持っています。

これは本当に必要ではないことに注意してください。Reactチームは、Reactクラスコンポーネントを非難する予定ではありません。また、すべてのReact Class Lifecycleメソッドがまだフックで可能であるわけではないことに注意する必要があります。もう少し長くReactコンポーネントクラスに固執する必要がある場合があります。

基本的なReactフックに関する新しい知識に十分に自信を持っている場合は、挑戦を残したいと思います。このカウントダウンタイマークラスを反応フックを使用してリファクタリングして、可能な限り清潔でコンパクトにする。

幸せなコーディング、そしてあなたがどのように乗るかを教えてください!

React HooksのFAQ

反応フックとは何ですか?

Reactフックは、機能コンポーネントのReact状態とライフサイクルの機能を「フック」できる機能です。それらは、クラスコンポーネントを作成せずに状態やその他の反応機能を有効にするためにReact 16.8で導入されました。

機能成分の状態論理の再利用を簡素化するために反応フックが導入され、コンポーネントの状態と副作用の管理が容易になりました。フック?

UseStateフックを使用して、機能コンポーネントに状態を追加できます。現在の状態値とそれを更新する関数を備えた配列を返します。 はい、単一の機能コンポーネント内のuseStateの複数のインスタンスを使用してEffectフックを使用して、異なる状態と効果を管理できます。

useContextフックは、機能コンポーネントのコンテキストにアクセスするために使用されます。コンテキスト消費者コンポーネントをレンダリングせずにコンテキスト値を消費できます。

ユーザーエディューザーフックは何に使用され、いつ使用する必要がありますか?

usereducerフックは、より複雑な国家管理のためにUseStateに代わるものです。予測可能な方法で状態遷移を管理する必要がある場合に役立ちます。

ビルトインフックまたはその他のカスタムフックを使用する関数を定義することにより、カスタムフックを作成できます。これらのカスタムフックは、コンポーネント間でステートフルなロジックをカプセル化して共有できます。

フックを使用するための重要なルールには、機能コンポーネントでのみ使用すること、上部レベルのフックを使用して(内部ループや条件付きではありません)、コンポーネントでの順序を確認することが含まれます。 >

Reactフックに関するパフォーマンス上の考慮事項はありますか?

正しく使用すると、Reactフックは不必要な再レンダーを減らすことでパフォーマンスを向上させることができます。ただし、USEMEMOとUSECALLBACKフックを使用して、必要に応じてパフォーマンスを最適化することが不可欠です。

以上がReactフック:あなた自身を始めて構築する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。