Reactベース入門の詳細


Reactプロジェクトの作成
1.cnpm i react react-dom -Sインストールパッケージ2を実行し、プロジェクトに関連する2つのパッケージを導入する.
// 1.   React    ,         react  react-dom
// 1.1 react    ,       React  、            ;
// 1.2 react-dom          DOM       ,  ,           
import React from 'react'
import ReactDOM from 'react-dom'

3、JSを使用した仮想DOMノードの作成:
// 2.   react  ,      DOM    ,     React     JS API    ,  【  】  Vue    ,   HTML   
// React.createElement()   ,       DOM   ,    3       
//   1:           ,          
//   2:        ,           ,     
//   3:            ,          DOM  ,    ,          
// 
div
var myH1 = React.createElement('h1', null, ' H1') var myDiv = React.createElement('div', { title: 'this is a div', id: 'mydiv' }, ' div', myH1)

4.ReactDOMを使用して、要素をページで指定されたコンテナにレンダリングします.
ReactDOM.render(myDiv, document.getElementById('app'))

ReactDOM.render(‘レンダリングする仮想DOM要素’,‘ページ上のどの位置にレンダリングするか’)注意:ReactDOM.render()メソッドの2番目のパラメータは、vueとは異なり、「#app」のような文字列を受け入れず、オリジナルのDOMオブジェクトを渡す必要がある
JSX構文
1、JSX構文を使用するには、cnpm i babel-preset-react -Dを実行してから、.babelrcに構文構成"presets": ["env", "stage-0", "react"]を追加する必要があります.2.JSX文法の本質:やはりReact.createElementの形式で実現され、ユーザーが書いたHTMLコードを直接ページにレンダリングしていない.3.もしJSX文法の内部で、JSコードを書くならば、それでは、すべてのJSコードは、{}内部に書かなければなりません;4.コンパイルエンジンがJSXコードをコンパイルするとき、<に遭遇したらHTMLコードとしてコンパイルし、{}に遭遇したらカッコ内のコードを普通のJSコードとしてコンパイルする.5.{}内部には、JS仕様に適合するコードを書くことができます.6.JSXで、要素にclassの属性を追加する場合は、classNameと書く必要があります.classはES 6でキーワードであるためです.classと同様に、labelラベルのfor属性をhtmlFor.7.1に置き換える必要があります.JSXでDOMを作成する場合、すべてのノードには、唯一のルート要素が包まれている必要があります.8.コメントを書く場合は、コメントを{}の内部に置く必要があります.
Reactはコンポーネントを作成する2つの方法
1.第一の基本コンポーネントの作成方法:構造関数で作成したコンポーネント
Hello.jsx
import React from 'react'
//   function       ,       props,     ,        
//   , class      ,       this.props      ,        props
export default function Hello(props) {
  // console.log(props)
  return 

haha --- {props.name}

}

2、第2のコンポーネントの作成方法:classキーワードに基づいてコンポーネントを作成する
Hello2.jsx
  • classを使用して作成されたクラスは、extendsキーワードを通じてReact.Componentを継承した後、このクラスは、コンポーネントのテンプレートです.
  • このコンポーネントを参照したい場合は、クラス名をラベル形式でJSXにインポートして使用できます.
  • 注意:extendsを使用して継承が実現された場合、constructorの最初の行には、必ずsuper()を呼び出し、super()は親クラスの構造関数を表す.
  • constructorでは、propsプロパティにアクセスするには、this.propsを直接使用するのではなく、constructorのコンストラクタパラメータリストに表示される定義propsパラメータを受信してから正常に使用する必要があります.
  • 注意:this.stateは現在のコンポーネントインスタンスのプライベートデータオブジェクトを表し、vueのコンポーネントインスタンスのdata(){return{}}関数のように、コンポーネントのstateのデータを使用する場合は、this.state.***から直接アクセスすればよい.
  • this.stateのデータに値を再割り当てする場合は、Reactはthis.setState({構成オブジェクト})を使用してstateに値を再割り当てすることを推奨します.注意:this.setStateメソッドは、定義された属性値を再上書きするだけで、最も完全な属性が指定されていない場合は、指定された属性値は上書きされません.
  • this.setStateメソッドは、functionを渡すこともサポートしています.functionが渡されている場合は、functionの内部でオブジェクトをreturnする必要があります.functionのパラメータでは、2つのパラメータの伝達がサポートされ、最初のパラメータはprevStateであり、修正前の古いstateデータとして表される.2番目のパラメータは、現在のコンポーネントに外部から伝達されるpropsデータ
  • である.
    import React from 'react'
    
    export default class Hello2 extends React.Component {
      constructor(props) {
        super(props)
        // console.log(props)
        this.state = {
          msg: '   Hello2      msg  ',
          info: 'test**'
        }
      }
      //     1: No `render` method found on the returned component instance: you may have forgotten to define `render`.
      //         ,  ,     ,  class        ,       render   
      render() {
        //     2: Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
        //         ,  ,  render    ,    return     ,         return  ,    return null
    
        //     React dev tools  ,       class      props     ,  ,      ,           props,     ;
        // this.props.address = '123'
        // console.log(this.props)
    
        return 

    class

    : {this.props.address} --- {this.props.info}

    {this.state.msg}

    } changeMsg = () => { // console.log('ok') // : , React , , this undefined, // console.log(this) // this.state.msg = '123' state , state , , ; // ,React , ; // this.state.msg = '123' /* this.setState({ msg: '123' }) */ this.setState(function (prevState, props) { // console.log(props) return { msg: '123' } }, function () { // this.setState , , , , console.log(this.state.msg) }) // , this.setState , , , this.setState , state // console.log(this.state.msg) } }

    {/*1.1 Reactでは、要素にイベントをバインドするには、Webページの従来のonclickイベントではなく、Reactが提供するonClick/}を使用する必要があります.{/1.2すなわち、Reactでは、提供されるイベントバインドメカニズムは、すべてアルパカネーミングを使用している.また、基本的には、従来のJSイベントは、Reactによって再定義され、アルパカネーミングonMouseMove/}に変更されている{/2.1 Reactが提供するイベントバインドメカニズムでは、イベントの処理関数は、functionの名前/}{/2.2を指定するのではなく、直接functionを指定する必要があります.Reactイベントバインド処理関数の場合、this.関数名によって、関数の参照をイベント*/}に渡す必要があります.
    コンポーネントの作成方法の2つの比較
    1、コンストラクション関数で作成されたコンポーネント:プロの名前を「ステータスなしコンポーネント」2、classキーワードで作成されたコンポーネント:プロの名前を「ステータスありコンポーネント」
    コンストラクション関数で作成されたコンポーネントとclassで作成されたコンポーネントの本質的な違いは、state属性の有無です!!!
    CSSモジュール化の使用
    1、webpack.config.jsでcss-loaderのモジュール化を有効にすることができる:css-loader?modules&localIdentName=[name]_[local]-[hash:8]:global()を使用してグローバルスタイルを定義する
    コードdemo:
    Webpack.config.jsファイル:
    const path = require('path')
    const htmlWebpackPlugin = require('html-webpack-plugin')
    
    module.exports = {
      entry: path.join(__dirname, './src/main.js'),
      output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle.js'
      },
      plugins: [ //   
        new htmlWebpackPlugin({
          template: path.join(__dirname, './src/index.html'),
          filename: 'index.html'
        })
      ],
      module: {
        rules: [
          //      css-loader    modules   ,   CSS     
          { test: /\.css$/, use: ['style-loader', 'css-loader?modules&localIdentName=[name]_[local]-[hash:5]'] }, 
          { test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
          { test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=5000' },
          { test: /\.jsx?$/, use: 'babel-loader', exclude: /node_modules/ }
        ]
      }
    }
    

    .babelrcファイル:
    {
      "presets": ["env", "stage-0", "react"],
      "plugins": ["transform-runtime"]
    }
    

    main.js
    // JS      
    // 1.    React 
    import React from 'react'
    import ReactDOM from 'react-dom'
    
    //   JS  ,    DOM  
    // var myDiv = React.createElement('h1', { id: 'mydiv', title: 'ok' }, '    H1')
    var myDiv = 
    OKOKOK
    // Hello , import Hello from './components/Hello.jsx' import Hello2 from './components/Hello2.jsx' ReactDOM.render(
    , document.getElementById('app'))

    注意:以上の2つのコンポーネントを作成する方法には、本質的な違いがあります.その中でfunctionコンストラクション関数を使用して作成されたコンポーネントは、内部にstateプライベートデータがなく、外部から伝達されたデータを受信するために1つのpropsしかありません.classキーワードを使用して作成されたコンポーネントは、内部にはthis.propsという読み取り専用属性のほか、保存に特化しています.独自のプライベートデータを格納するthis.stateプロパティ.このstateは読み書き可能です.上の違いに基づいて、functionを使用して作成されたコンポーネントを「ステータスなしコンポーネント」、classを使用して作成されたコンポーネントを「ステータスありコンポーネント」と呼びます.状態コンポーネントと無状態コンポーネントがあり、最も本質的な違いはstate属性の有無である.同時に、classが作成したコンポーネントは、自分のライフサイクル関数を持っているが、functionが作成したコンポーネントは、自分のライフサイクル関数を持っていない.
    質問です.ステータスのあるコンポーネントを使用するのはいつですか.ステータスのないコンポーネントを使用するのはいつですか.1、1つのコンポーネントが自分のプライベートデータを保存する必要がある場合、またはコンポーネントの異なる段階で異なるビジネスロジックを実行する必要がある場合、classで作成したステータスのあるコンポーネントに非常に適しています.2、1つのコンポーネントであれば、外部から伝達されたpropsだけが必要です、固定されたページ構造をレンダリングするのは終わりです.この場合、functionを使用して作成されたステータスレスコンポーネントに適しています.(ステータスレスコンポーネントを使用する小さなメリット:コンポーネントのライフサイクルが取り除かれているため、実行速度が比較的速い)
    リストおよびスタイルdemo CommentList.jsx
    import React from 'react'
    
    //             
    import CommentItem from './CommentItem.jsx'
    
    //       
    export default class CommentList extends React.Component {
      constructor(props) {
        super(props)
    
        //                 
        this.state = {
          cmts: [
            { user: '  ', content: '  ' },
            { user: '  2', content: '  ' },
            { user: '  3', content: '  ' },
            { user: '  4', content: '  ' },
            { user: '  5', content: 'test' }
          ]
        }
      }
    
      //         , render       ,  ,       DOM       
      render() {
        //#region           1,  low,   JSX   JS         
        /* var arr = []
        this.state.cmts.forEach(item => {
          arr.push(

    {item.user}

    ) }) */ //#endregion return

    {/* JSX , map , , map */} {this.state.cmts.map((item, i) => { // return return })}
    } }

    CommentItem.jsx
    import React from 'react'
    //   :     import    ,import             
    import inlineStyles from './cmtItemStyles.js'
    
    //           【     import '../     '   CSS     ,       CSS】
    // import '../../css/commentItem.css'
    //      ,      CSS      ,      itemStyles      ,   .css     ,       JS   export defualt     
    
    //     CSS      ,          itemStyles            ,
      ,               ,   ,             (      )
    import itemStyles from '../../css/commentItem.css'
    console.log(itemStyles)
    
    //            ,                ,             
    export default function CommentItem(props) {
      //   :       style   ,  JSX      DOM  ,    ,           ;     JS      
      //     style      ,    { }      JS   ,    { }       JS      
      //   :   style       ,           px,   px     ,           
    
    
      //#region     1
      /*  const boxStyle = { border: '1px solid #ccc', margin: '10px 0', paddingLeft: 15 }
       const titleStyle = { fontSize: 16, color: "purple" }
       const bodyStyle = { fontSize: 14, color: "red" } */
      //#endregion
    
    
      //#region     2       ,           
      /* const inlineStyles = {
        boxStyle: { border: '1px solid #ccc', margin: '10px 0', paddingLeft: 15 },
        titleStyle: { fontSize: 16, color: "purple" },
        bodyStyle: { fontSize: 14, color: "red" }
      } */
      //#endregion
    
    
      /* return 

    :{props.user}

    :{props.content}

    */ // : vue scoped , , react return

    :{props.user}

    :{props.content}

    }

    cmtItemStyles.js
    //           
    export default {
      boxStyle: { border: '1px solid #ccc', margin: '10px 0', paddingLeft: 15 },
      titleStyle: { fontSize: 16, color: "purple" },
      bodyStyle: { fontSize: 14, color: "red" }
    }