React-3

66055 ワード

シンボルを表すJSX


JSXはJavaScript XMLの略で、JavaScriptにXMLを追加する拡張構文として理解される.
反応エンジンはJSXのXML構造を解析しJavaScript関数コードに変換する.
React.createElement()関数は反応エンジンに含まれます.
既存のJavaScriptのドキュメント.createElement()関数を使用してオブジェクトモデルを作成します.
応答を使用すると、開発者はJSXを作成するだけで、応答エンジンはJSXを既存のJavaScriptに解析するだけです.
これを「宣言ビュー」(Declarative View)テクノロジーと呼びます.
import React from 'react';

class App extends React.Component {
  render() {
    return (
      <div>
        <img src=".../image.png" />
        <div>안녕하세요</div>
      </div>
    );
  }
}
// 위 구문을 아래로 해석해주는 작업을 리액트 엔진이 합니다.
return React.createElement(
    'div',
    null,
    React.createElement('img', { src: './image.png' }),
    React.createElement('div', null, '안녕하세요'),
  );

構成部品とアセンブリ


構成部品とは
  • 既存のMVCはコードを効率的に管理できるが,相互依存性が高く回収が困難である.
  • Webサイトの画面の各要素は似ており、
  • を繰り返し使用しています.
  • 要素はMVCビューとは独立して再利用可能であり、要素による新規要素の作成が容易である
  • .
    構成部品アセンブリ
    データコンポーネント
    特長
    保証する
    親構成部品から子構成部品に渡される読み取り専用データ
    state
    構成部品ステータスのデータを保存および変更できます.
    コンテキスト
    親構成部品によって作成され、すべての子構成部品に渡されるデータ.

    構成部品にデータを渡すプロセス


    上の図に示すように、
  • Propertyは、親コンポーネントから子コンポーネント(すなわち、一方向データストリーム)への特徴を有する.
  • Propertyは、すべてのデータ型を提供します.(Propertyのデータ型を事前に宣言することをお勧めします.)データ型宣言はprop-typesであってもよい.
  • Propertyに値を渡す場合、文字列「」の場合、それ以外にデータ型にはカッコ{}で値を入力する必要があります.
  • import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    
    class ChildComponent extends Component {
      render() {
        const { boolValue, numValue, arrayValue, objValue, nodeValue, funcValue } = this.props;
        return (
          <div>
            <span>{boolValue}</span>
            <span>{numValue}</span>
            <span>{arraylValue}</span>
            <span>{objValue}</span>
            <span>{nodeValue}</span>
            <span>{funcValue}</span>
          </div>
        );
      }
    }
    
    ChildComponent.propTypes = {
      boolValue: PropTypes.bool,
      numValue: PropTypes.number,
      arrayValue: PropTypes.array,
      objValue: PropTypes.object,
      nodeValue: PropTypes.node,
      funcValue: PropTypes.func,
      //필수 자료형 지정 방법 : PropTypes.자료형.isRequired;
    };
    //default 기본값 지정방법
    ChildComponent.defaultProps = {
      boolValue: false,
    };
    
    export default ChildComponent;
    
    //app.js childComponent의 상위 컴포넌트
    import React from 'react';
    import ChildComponent from './03/ChildComponent';
    
    class App extends Component {
      render() {
        return (
          <ChildComponent
            boolValue={true}
            numValue={3}
            arrayValue={[1, 2, 3]}
            objValue={{ name: 'name', age: 30 }}
            nodeValue={<h1>Node</h1>}
            funcValue={() => {
              console.log('message');
            }}
          ></ChildComponent>
        );
      }
    }

    構成部品ステータスの管理


    ステータス管理
    Propertyとは異なり、Stateは、値を変更するイベント(数)など、変更が必要な値に使用できる変更可能な値です.
    Ex:4秒後に状態を変更する例
    import React, { Component } from 'react';
    
    class StateExample extends Component {
      constuctor(props) {
        super(props);
        //state 정의
        this.state = {
          loading: true,
          formData: 'no data',
        };
        this.handleData = this.handleData.bind(this);
    
        setTimeout(this.handleData, 4000);
      }
      handleData() {
        const data = 'new data';
        const { formData } = this.state;
        this.setState({
          loading: false,
          formData: data + formData,
        });
        console.log('loading값', this.state.loading);
        //render 함수전 loading 값은 아직 변하지 않은 true입니다.
      }
      render() {
        return (
          <div>
            <span>{String(this.state.loading)}</span>
            <span>{this.state.formData}</span>
          </div>
        );
      }
    }
    
    export default StateExample;
    stateの使用上の注意
  • 作成者で初期化する必要があります.
    これは、内部関数からステータス値にアクセスするために必要です.適切な初期値がない場合は、空のオブジェクト({})を配置する必要があります.
  • ステータス値を変更する場合は、setState()関数(ステータス管理関数)を使用する必要があります.
    反応エンジンはrender()を使用してスクリーンを描くタイミングを決定するからです.ステータス値を直接変更してもrender()関数は呼び出されません.これは、今後学習するライフサイクルと密接に関連しています.
  • setState()関数は非同期で処理され、setState()コードが実行された後に接続された関数の場合にスクリーン同期が行われる.
  • 関数をsetState()関数のパラメータとして渡すことで,以前の状態値を容易に得ることができる.
    handleData(data) {
        this.setState(function(prevState){
            const newState = {
                loading : false,
                formData : data + prevState.formData,
            };
            return newState;
        });
    }
    
    handleData(data) {
        this.setState(prevState => ({
            loading : false,
            formData : data + prevState.formData,
        });
    }
    クラスインスタンス変数とforceUpdate()関数を使用してステータスを管理
    forceUpdate()関数:クラスインスタンス変数と画面を強制的に出力するための関数.値をsetStateに変更し、応答エンジンに画面出力を渡した場合は、この関数の出力を強制的に実行できますが、応答性能に制限されているため、画面を再出力しない限り、この関数を使用しないことをお勧めします.
    import React, { Component } from 'react';
    
    class StateExample extends Component {
      constuctor(props) {
        super(props);
    
        //state 정의
        this.loading = true;
        this.formData = 'no data';
    
        this.handleData = this.handleData.bind(this);
    
        setTimeout(this.handleData, 4000);
      }
      handleData() {
        const data = 'new data';
        this.loading = false;
        this.formData = data + this.formData;
        //강제 화면 새로고침
        this.forceUpdate();
      }
      render() {
        return (
          <div>
            <span>{String(this.loading)}</span>
            <span>{this.formData}</span>
          </div>
        );
      }
    }
    
    export default StateExample;

    構成部品のライフサイクル


    構成部品の作成から消滅までのプロセスを構成部品のライフサイクルと呼びます.各ライフサイクルには関数があり、これらの関数を使用して特定の時点で必要な操作を実行できます.

    図に示すように、作成中に4つの関数を使用し、作成完了後に更新(update)するときに5つの関数を使用します.shouldComponent()関数の戻り値は、後続のプロシージャをスキップするかどうかを決定します.破棄プロセスには関数が使用されます.
  • 構造関数(props)関数
    ステータスを宣言するには、最初の作成時に1回のみ呼び出されます.この関数を定義する場合は、初期化プロセスやライフサイクルステータスなどの重要なプロセスを含むsuper()関数を常に最上位に呼び出す必要があります.
  • render()関数
    この関数は、データが変更され、新しい画面を描画する必要がある場合に自動的に呼び出される関数です.この関数が返すJSXを画面に描画します.
  • 静的getDerivedStateFromProps(props,state)関数
    この関数は静的関数です.したがって、関数ではthis.道具かこれかstatで構成またはステータス値にアクセスできません.各値にアクセスする必要がある場合は、パラメータとして渡されるprops、stateを使用する必要があります.この関数は主に、親構成部品から渡された構成にステータス値を関連付け、ステータスを戻り値に変更するために使用します.
  • コンポーネントDidMount()関数
    この関数はrender()関数が画面を描いた後に呼び出される関数です.
  • shouldComponent Update(NextProps,NextState)関数
    この関数は、画面を再出力し、データの変化を比較する操作を含むかどうかを決定し、応答性能に大きく影響します.forceUpdate()関数を呼び出すと呼び出されません.
  • getSnapshotBeforeUpdate関数
    この関数は、仮想画面で構成部品の変更を完了した後に呼び出される関数です.デバイスが実際の画面に出力される前にDOM情報にアクセスするために使用されます.
  • コンポーネントDidUpdate関数
    実際の画面に出力して呼び出された関数.前のプロセスと前のステータス値、および以前に呼び出されたgetSnapshotBeforeUpdate()関数の戻り値snapshotをパラメータとして渡します.これらの値はDOM情報を変更するために使用されます.
  • コンポーネントWillUnmount()関数
    構成部品が消える前に呼び出される関数.通常、構成部品で監視されている動作を閉じる関数です.
  • クラス構成部品


    反応ライフサイクル関数と素子コンポーネントに含まれる特徴があります.
  • Component
  • import React from 'react';
    class MyComponent extends React.Component{
      constructor(props){
        super(props);
        console.log('생성 함수');
      }
      componentDidMount(){//상속받은 생명주기 함수}
      myMethod() {//추가 확장 함수}
      render() {//상속박은 화면 출력 함수}
        
        
  • PureComponent
    PureComponentクラスは、コンポーネントクラスの継承クラスです.
    違いは、shouldComponentUpdate()関数を「比較的浅い」ように再定義したことです.簡単な比較でパフォーマンスを向上させることができます.可変パラメータでパフォーマンスを向上させることもできます.
  • の浅い比とは何ですか?
    浅い-等しいライブラリの浅いEqual()関数を使用して比較します.
  • const obj = {name:'park'};
    const mylist = [1,2,3,obj];
    const list1 = [1,2,3,obj];
    const list2 = [1,2,3,{name:'park'};
    
    mylist === list1;
    // false ===같은 경우 깊은 비교를 함
    shallowEqual(mylist,list1);
    //true로 다른 배열이지만 내용물이 같아서 동일 취급             
    shallowEqual(list1,list2);// false obj라는 객체 내용은 같지만 
    //list1 = 1,2,3,obj | list2= 1,2,3,{name:'park'} 이라 다르게 인식
    

    関数構成部品


    関数型素子は、無状態の関数型素子SFCと呼ばれ、やや長く表示される.したがって、簡単なUI構造のコンポーネントを作成するために使用することができる.
    プロセス
    データ(Property,コンテキスト)->関数コンポーネント->出力するコンポーネント(JSX)
    単純な構造
    import React from 'react';
    import PropTypes from 'prop-types';
    
    function SFC(props, context) {
      const {somePropValue} = props;
      const{someContextValue} = context;
      return <h1> hello, {somePropValue}</h1>
    }
    export default SFC;

    アレイ構成部品


    掲示板やYouTubeのビデオディレクトリはどのように実現されていますか?
    JavaScript配列で構成されています.XMLとJSXは、異なるデータ型を格納することもできるので、繰り返し処理が必要な場合は、アレイコンポーネントの使用が容易になります.
    map()関数の使用方法
    import React from 'react';
    class TodoList extends React.PureComponent{
      render() {
    	const todoList = [
          { taskName: "빨래하기" , finished: false},
          { taskName: "공부하기" , finished: true},
          ];
        return(
          <div>
          {todoList.map((todo) => <div key={todo.taskName}>{todo.taskName}</div>)}
        </div>
        );
      }
    }
    export default TodoList;
    mapは、素子の繰り返し配列を可能にする.
    パターン要素の数を繰り返すため、キー値をキー値として定義する必要があります.これにより、パフォーマンスに大きな影響を与えます.キー値を定義して出力するアレイ要素で、再出力が必要な場合は、反応エンジンは既存の要素を再利用してパフォーマンスを向上させることができます.
    キー値を単純に繰り返し(i)の値に減らし、filter関数を使用してフィルタリングすると、キー値を変更するたびに回収および再描画ができなくなり、効率が低下します.
    {todoList.filter(todo => todo.finished).map((todo, i)=>(
      <div key={`tl_${i}`}>{todo.taskName}</div>
    ))}

    構成部品のコールバック関数とイベントの処理


    Propertyの場合、親から子への一方向の流れを表しますが、子から変更する場合はどうすればいいですか?サブエレメントには、断面ビームを変更できるクラス関数を指定できます.
    コールバック関数とは、定義された場所で実行される関数ではなく、特定の状況で実行される関数です.すなわち,コールバック関数をpropertyに渡すだけでよい.
    import React from 'react';
    import Counter from './03/Counter';
    
    class App extends React.Component{
      constructor(props){
    	super(props);
        this.state = {
          	count: 1,
        };
      }
      increaeCount() {
    	this.setState(({ count}) => ({ count: count +1}));
      }
      render() {
        	return (
              //<Counter count={this.state.count} onAdd={this.increaseCount} />
              // 콜백함수 선언
              <Counter count={this.state.count} 
      		   onAdd={this.increaseCount.bind(this)} />
    // 콜백함수 선언시 bind를 해주지 않으면 상위 App컴포넌트에는 this.setState(...)
    // 에 정의되어 있는데 실행은 하위 컴포넌트에서 실행되기 때문에 
    // 해당 함수를 찾을수 없다는 문제가 발생합니다.
             
              );
      }
    }
    export default App;
    
    //Counter 구현
    class Counter Extends React.Component {
      render() {
        return (
          <div>
          현재 카운트: {this.props.count}
      	<button onClick=(() => this.props.onAdd()}>카운트 증가</button>
    	</div>
    );
    }
    }
    DOMオブジェクト関数を構成部品に使用する
    構成部品でDOMオブジェクト関数を使用するには、「特殊な輪郭」(ref)を使用する必要があります.ただし、refpropertyは、DOMオブジェクト関数を必要とするエンティティにコールバック関数として渡される.
    import React, { PureComponent } from 'react';
    
    export default class ScrollSpy extends PureComponent {
      constructor(props) {
        super(props);
        this.setRef = this.setRef.bind(this); 
        this.checkPosition = this.checkPosition.bind(this); 
        
      }
      setRef(ref) {
        this.ref = ref;
        //ref 프로퍼티에서 반환된 객체를 컴포넌트 변수에 할당했습니다.
      }
      checkPosition() {
        if (this.ref.getBoundingClienRect().top < window.innerHeight) {
          console.log('enter');
        } else {
          console.log('exit');
        }
      }
      componentDidMount() {
        this.checkPosition();
        window.addEventListener('scroll', this.checkPosition); // 윈도우 스크롤 이동 이벤트를 감지하여 checkPosition함수가 실행 되도록
      }
      componentWillUnmount() {
        window.removeEventListener('scroll', this.checkPosition);
      }
      render() {
        return <div ref={this.setRef}></div>;
      }
    }
    

    Input構成部品の作成時の復習

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    
    class Input extends Component {
      constructor(props) {
        super(props);
        this.setRef = this.setRef.bind(this);
        this.handleChange = this.handleChange.bind(this);
      }
      handleChange(e) {
        const { name, onChange } = this.props;
    
        if (onChange) {
          onChange(name, e.target.value);
        }
      }
    //autoFocus 값이  true 일경우 ref = document.ElementById().focus();
      componentDidMount() {
        if (this.props.autoFocus) {
          this.ref.focus();
        }
      }
      componentDidUpdate() {
        if (this.props.autoFocus) {
          this.ref.focus();
        }
      }
      setRef(ref) {
        this.ref = ref;
      }
      render() {
        const { errorMessage, label, name, value, type, onFocus } = this.props;
        return (
          <label>
            {label}
            <input
              id={`input_${name}`}
              ref={this.ref}
              onChange={this.handleChange} // 값 변경시 handle~ 함수호출 
              onFocus={onFocus} // 상위 컴포넌트의 콜백함수 호출 onFocus시
              value={value}
              type={type}
            />
            {errorMessage && <span className="error">{errorMessage}</span>}
          </label>
        );
      }
    }
    
    Input.propTypes = {
      type: PropTypes.oneOf(['text', 'number', 'price']),
      name: PropTypes.string.isRequired,
      value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
      errorMessage: PropTypes.string,
      label: PropTypes.string,
      onChange: PropTypes.func,
      onFocus: PropTypes.func,
      autoFocus: PropTypes.bool,
    };
    Input.defaultProps = {
      onChange: () => {},
      onFocus: () => {},
      autofocus: false,
      type: 'text',
    };
    
    export default Input;