userMemo混同の原因と解決方法(feat.rendering)


💡 緒論


私学のreactなので、しっかり身につけておきたいと思います.
現在、第1話の精読挑戦2日目、反応フックを見ている.
ただし、レンダリングに慣れていないためか、usemo部分が混同されています.
個人的には『私が混同したら他の人も混同する』と思います.きっとこの文章を調べた人がやったに違いない.
そのため、個人的な混乱を防ぐために、自分の足りないところを整理して、探してみると、ある程度好奇心が解消されます.
これは初級者の目に映る定理なので、不完全なところに注意してくださいが、それらの根拠は出典を残します.スタート!

💡 本題


次のコードを見てください.

App.js


import React, {StrictMode} from 'react';
import Average from './Average/Average';


function App() {
  return (
    <StrictMode>
      <Average />
    </StrictMode>
  )
};

export default App;

Average.js


userMemoを使用する前に
import React, { useState } from 'react'

const getAverage = numbers => {
    console.log('평균 값 계산 중...');
    if (numbers.length === 0) return 0;
    const sum = numbers.reduce((a, b) => a + b);
    return (sum / numbers.length);
}

function Average() {
    const [list, setList] = useState([]);
    const [number, setNumber] = useState('');
    
    const onChange = e => {
        setNumber(e.target.value);
    }
    const onInsert = e => {
        if (number === '') return;
        const nextList = list.concat(parseInt(number));
        setList(nextList);
        setNumber('');
    }

    return (
        <div>
            <input value={number} onChange={onChange} />
            <button onClick={onInsert}>등록</button>
            <ul>
                {list.map((value, index) => (
                    <li key={index}>{value}</li>
                ))}
            </ul>        
            <div>
                <b>평균값:</b> {getAverage(list)}
            </div>
        </div>
    );
};

export default Average;
本素子の目的である「平均計算」については、良好に動作する.

問題は
  • onChangeによる
  • 数の状態が変化し、
  • .
  • レンダー
  • これは
  • getaverageに影響します.
  • 私がここで気になったのは、「必ずしもusemoを使わなければならないとは限らないのではないか」ということです.はい.これはAverage関数の外部に関数が記述されているためである.
    それでも操作はonChangeの影響を受けるため,Memoの使用が必要であることは理解できない.
    さあ、今からusemoを使います.
    使用後
    import React, { useState, useMemo } from 'react'
    
    const getAverage = numbers => {
        console.log('평균 값 계산 중...');
        if (numbers.length === 0) return 0;
        const sum = numbers.reduce((a, b) => a + b);
        return (sum / numbers.length);
    }
    
    const trash = () => {
        console.log('나도 계산중...')
    }
    
    function Average() {
        const [list, setList] = useState([]);
        const [number, setNumber] = useState('');
        
        const onChange = e => {
            setNumber(e.target.value);
        }
        const onInsert = e => {
            if (number === '') return;
            const nextList = list.concat(parseInt(number));
            setList(nextList);
            setNumber('');
        }
        trash();
        //렌더링
        const avg = useMemo(() => getAverage(list), [list]);
    
        return (
            <div>
                <input value={number} onChange={onChange} />
                <button onClick={onInsert}>등록</button>
                <ul>
                    {list.map((value, index) => (
                        <li key={index}>{value}</li>
                    ))}
                </ul>        
                <div>
                    <b>평균값:</b> {avg}
                </div>
            </div>
        );
    };
    
    export default Average;
    
    useMemoの結果はgetaverageの計算時のみ良好に動作します.
    では、今から私たちの悩みを解決しましょう.
    明らかに別の関数で記述されていますが、レンダリングはなぜですか?
    手順に従って考えるなら、関連部分のはずです.
  • onChangeによる
  • 数の状態が変化し、
  • .
  • レンダー
  • これは
  • getaverageに影響します.
  • 実際、useMemoはレンダリング中に値を変更した場合にのみ演算を実行し、値が変わらない場合は前の演算をコメントします.
    ソース-React Hooks APIリファレンス
    すなわち,usemoが混同されると,問題の根源はレンダリングに対する理解の欠如である.
    では、レンダリングについてもう一度理解しましょう.

    📖 レンダー(Render)


    反応図では、レンダリングは、いくつかのコードの結果を直感的に表示するために行われる.ソース-ブログ
    これらのレンダリングは、リアクターで4つの場合に実行されます.ソース
  • 自分の状態が変わるとき
  • 親構成部品の再レンダリング
  • propsの変更
  • forceUpdate関数
  • を実行
    その中で、自分の状態が変わったときを見てみましょう.
    最終的には、以前に作成したコードもAverageというコンポーネントでエクスポートされ、Averageにはnumberというstateがあります.
    つまり.
  • Average->onChangeイベント検出
  • 号状態変化
  • Averageコンポーネント再提示運転
  • で返されると、getaverage関数も再レンダリングに影響します.
  • 表示されます.
    これを理解していない場合は、上のコードの戻り値の次のconsoleを使用します.ログを実行します.
    return (
            <div>
                {console.log('저는 리렌더링되고 있습니다.')}
                <input value={number} onChange={onChange} />
               	(...)

    レンダリングを続行します.

    💡 n/a.結論


    問題は次から始まります.
    レンダリングで外部にある関数getaverage()にも影響する理由
    解決策は次のとおりです.
    レンダリングの操作条件では、
    1.number stateの変化による
    2.構成部品の戻り値部分のレンダリングを続行します.
    3.リターンに属するgetaverage()に影響します.
    悟ったのは、最終的には振り向いて、まず反応が始まる原理を正しく理解してこそ、よく勉強することができるということだ.
    やっぱり探しながら勉強するのは面白いと思います!!😊😊