<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>SaGo_MunGcci.log</title>
        <link>https://velog.io/</link>
        <description>이리저리 생각만 많은 사고뭉치입니다.</description>
        <lastBuildDate>Fri, 04 Apr 2025 21:28:26 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>SaGo_MunGcci.log</title>
            <url>https://velog.velcdn.com/images/sago_mungcci/profile/a80df289-1c1f-4008-bc23-5b05a0d54e18/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. SaGo_MunGcci.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/sago_mungcci" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[2024.04.05]]></title>
            <link>https://velog.io/@sago_mungcci/2024.04.05</link>
            <guid>https://velog.io/@sago_mungcci/2024.04.05</guid>
            <pubDate>Fri, 04 Apr 2025 21:28:26 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2024.02.08]]></title>
            <link>https://velog.io/@sago_mungcci/2024.02.08</link>
            <guid>https://velog.io/@sago_mungcci/2024.02.08</guid>
            <pubDate>Sat, 08 Feb 2025 00:56:33 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[2023.11.30 TIL(DAS NAS SAN)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.11.30-TILDAS-NAS-SAN</link>
            <guid>https://velog.io/@sago_mungcci/2023.11.30-TILDAS-NAS-SAN</guid>
            <pubDate>Thu, 30 Nov 2023 00:49:42 GMT</pubDate>
            <description><![CDATA[<ul>
<li>DAS<ul>
<li>일반적인 USB, 외장하드와 같이 해당 PC와 직접적으로 연결하는 방식</li>
</ul>
</li>
</ul>
<ul>
<li>NAS</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/45c32687-33c6-44a7-9e8b-f6fbfd0c268b/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/2b8c8a48-2010-4065-8601-5726f6cef888/image.png" alt=""></p>
<ul>
<li>NAS와 SAN의 차이점
<img src="https://velog.velcdn.com/images/sago_mungcci/post/7676072b-c411-4d85-bb6e-de0a73fee6c7/image.png" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[2023.11.24 TIL(채팅앱만들기1)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.11.24-TIL%EC%B1%84%ED%8C%85%EC%95%B1%EB%A7%8C%EB%93%A4%EA%B8%B01</link>
            <guid>https://velog.io/@sago_mungcci/2023.11.24-TIL%EC%B1%84%ED%8C%85%EC%95%B1%EB%A7%8C%EB%93%A4%EA%B8%B01</guid>
            <pubDate>Sun, 26 Nov 2023 09:42:41 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/dfd0b507-cb68-4f7b-828d-c501c8d3c72d/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<p>⦁ TCP클라이언트 | 서버 구성</p>
<hr>
<br>

<h2 id="til">TIL</h2>
<p>클라이언트</p>
<pre><code class="language-js">Imports System.Net
Imports System.Text.Unicode

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        &#39;tcp연결을 한다.
        &#39;포트넘버사용시 주의점 : 이미 사용중인 포트넘버를 사용하면 안된다.
        &#39;내가현재 어떤 포트를 사용하고 있는지 확인하는 방법은
        &#39;cmd =&gt; netstat -n입력 하면 로컬 주소에 맨 마지막 번호가 포트넘버이다.
        &#39;혹시 1300번을 사용하는지 cmd에서 확인하고 싶으면
        &#39;netstat -n | find &quot;13000&quot;입력한뒤에 아무것도 안나오면 사용안함
        &#39;Net.Sockets.TcpClient(&quot;접속하곳의 주소&quot;, &quot;포트넘버&quot;)
        &#39;127.0.0.1 로컬호스트 주소
        Dim client As New Net.Sockets.TcpClient(&quot;127.0.0.1&quot;, 13000) &#39;TCP연결완료

        &#39;TCP통신에서 사용하는 네트워크를 통한 데이터를 활용할 수있는 함수가 제공되는데
        &#39;netWorkStream이라는 곳에 담겨있다.
        &#39;GetStream() 네트워크 스트림 형태의 데이터를 반환한다.
        &#39;Dim networkStream As Sockets.NetworkStream = client.GetStream()
        Dim networkStream As Sockets.NetworkStream = client.GetStream()

        &#39;아래와 같이
        &#39;networkStream.Write, networkStream.Read() 매서드를 사용함으로써
        &#39;TCP의 규정을 일일이 맞춰서 데이터를 구축하지 않아도 된다. 
        Dim sentence As String = &quot;Hello VB&quot;
        &#39;String 문자열을 바이트배열로 인코딩해서 넣어줌
        Dim data As Byte() = System.Text.Encoding.Default.GetBytes(sentence)
        &#39;networkStream.Write(&quot;보내고 싶은 데이터&quot;, &quot;데이터의 몇번째부터 보낼건지&quot;, &quot;어디까지&quot;)
        networkStream.Write(data, 0, data.Length)

        Debug.WriteLine(&quot;전송문구 : &quot; &amp; sentence)

        &#39;중요!
        &#39;*****두개다 사용했으면 항상 닫아야 한다.*****
        networkStream.Close()
        client.Close()

    End Sub
End Class

</code></pre>
<p>서버</p>
<pre><code class="language-js">Imports System
Imports System.Net
Imports System.Net.Sockets

Public Class Form1

    Dim server As TcpListener

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        &#39;데이터 받기
        &#39;TcpListener에서 아이피주소 String 형태로 못받음
        &#39; 따라서 IPAddress 클래스에서 String 문자열을 ip주소로 바꿔줘야함.

        Dim localAddress As IPAddress = IPAddress.Parse(&quot;127.0.0.1&quot;)
        server = New TcpListener(localAddress, 13000)

        &#39;위에 2개를 만들면 tcp리스너를 만든것인데 이걸 만들었다고 바로 동작하지 않는다
        &#39;준비만 한 상태이다.
        &#39;동작 스위치를 켜줘야한다.
        &#39;server.Start() 후 부터 server.Stop()할때 까지
        &#39;데이터들이 큐에 적재되어 대기하기 시작한다.
        &#39;또 server.Start(20) 큐에 20만큼 데이터가 차면 그이상 안받는다. 
        server.Start()
        Debug.WriteLine(&quot;서버가 시작했습니다.&quot;)

        &#39;server.AcceptTcpClient()
        &#39;보류중인 큐에 대기중인 요청을 수락하는데
        &#39;반환값이 TcpClient이다.
        &#39;따라서 아래와 같이 사용한다.
        &#39;Dim client As TcpClient = server.AcceptTcpClient()

        &#39;아래 매서드 2개는 비슷하다.
        &#39;요청이 끝난후 새로운 데이터가 큐에 쌓여서 대기상태가 되면
        &#39;여기서 멈춘다.
        &#39;Dim client As TcpClient = server.AcceptTcpClient()
        &#39;client.GetStream().Read()

        &#39;Dim client As TcpClient = server.AcceptTcpClient()

        &#39;만약 위에서 멈추게 되면 난감한데
        &#39;server.Pending() 해결할수 있다.
        &#39;연결이 보류 중이면 true, 아니면 false이다.

        &#39; 위와 같이되면 서버 스타트 부터 펜딩까지 시간에 들어온 요청만 받게된다.
        &#39; 해결방안
        &#39; 1. 서버시작 버튼과 페딩버튼을 나누어서 해결
        &#39; 2. 아래 팬딩 if문을 무한 루프로 계속 데이터를 받을 수있게 함
        &#39; 예제는 2번
        &#39; 아래와 같이 하면 무한루프때문에 UI먹통,
        &#39; OS단에서 버그로 판단해 자동으로 프로그램 종료를 해버린다.
        &#39; 버튼을 2개 만들자
        &#39;While True
        &#39;    If server.Pending() Then
        &#39;        &#39;연결 보류중이면
        &#39;        Dim client As TcpClient = server.AcceptTcpClient()
        &#39;        Debug.WriteLine(&quot;클라이언트가 접속했습니다.&quot;)
        &#39;        Exit While
        &#39;    Else
        &#39;        &#39;아니면
        &#39;    End If
        &#39;End While

        &#39;server.Stop()
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

        &#39;Try
        &#39;    If server.Pending() = Nothing Then
        &#39;        MsgBox(&quot;서버시작부터 눌러주세요&quot;)
        &#39;        Return
        &#39;    End If
        &#39;Catch ex As System.NullReferenceException
        &#39;    MsgBox(&quot;서버시작부터 눌러주세요&quot;)
        &#39;    Return
        &#39;End Try


        If server.Pending() Then
            &#39;연결 보류중이면
            Dim client As TcpClient = server.AcceptTcpClient()
            Debug.WriteLine(&quot;클라이언트가 접속했습니다.&quot;)
            server.Stop()
        Else
            &#39;아니면
        End If

    End Sub
End Class
</code></pre>
<hr>
<br>


<h2 id="retrospection">Retrospection</h2>
<hr>
<br>
]]></description>
        </item>
        <item>
            <title><![CDATA[2023.11.24 TIL(기본강의5)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.11.24-TIL%EA%B8%B0%EB%B3%B8%EA%B0%95%EC%9D%985</link>
            <guid>https://velog.io/@sago_mungcci/2023.11.24-TIL%EA%B8%B0%EB%B3%B8%EA%B0%95%EC%9D%985</guid>
            <pubDate>Sat, 25 Nov 2023 07:28:22 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/d9d1c9f7-f6f3-4611-9cc4-e4b731ea2300/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<p>⦁ 로또번호 생성</p>
<hr>
<br>

<h2 id="til">TIL</h2>
<pre><code class="language-js">
Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub

    &#39;로또번호 생성시작
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Start()
    End Sub

    &#39;비우기
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Empty()
    End Sub

    &#39;끝내기
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

        AppOff()
    End Sub

    &#39;메뉴스트립 :  버튼 단축키 디자인단에 메뉴 시작 클릭해서 shortcutKeys등록하면됨
    &#39;나머지도 마찬가지
    Private Sub 시작ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 시작ToolStripMenuItem.Click
        Start()
    End Sub

    Private Sub 비우기ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 비우기ToolStripMenuItem.Click
        Empty()
    End Sub

    Private Sub 끝내기ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 끝내기ToolStripMenuItem.Click
        AppOff()
    End Sub


    &#39;컨택스트 메뉴스트립 : 버튼 디자인에 form클릭해서
    &#39;컨택스트메뉴스트립에 등록해야한다. *****중요*****
    Private Sub 시작ToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles 시작ToolStripMenuItem1.Click
        Start()
    End Sub

    Private Sub 비우기ToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles 비우기ToolStripMenuItem1.Click
        Empty()
    End Sub

    Private Sub 끝내기ToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles 끝내기ToolStripMenuItem1.Click
        AppOff()
    End Sub

    Private Sub Start()
        &#39; 랜덤 객체 생성
        Dim rand As New Random()
        &#39;사용후 항상 클리어
        Dim arrList As ArrayList = New ArrayList()
        Dim randomNumber As Integer = 0

        Dim checkOk As Boolean = True
        &#39;EXIT While
        While checkOk

            For i = 0 To 5 Step 1
                &#39; 1부터 10까지의 랜덤한 숫자 생성
                &#39; 아래와 같이 1,45면 1~44까지의 번호만 출력된다.
                &#39;randomNumber = rand.Next(1, 45)
                randomNumber = rand.Next(1, 46)

                If arrList.Contains(randomNumber) Then
                    Debug.WriteLine(&quot;이미 존재하는 &quot; + randomNumber.ToString() + &quot;이 있습니다&quot;)
                    arrList.Clear()
                Else
                    arrList.Add(randomNumber)
                End If

            Next

            If arrList.Count &lt; 6 Then
                checkOk = True
            Else
                checkOk = False
            End If

        End While

        Label1.Text = arrList(0).ToString()
        Label2.Text = arrList(1).ToString()
        Label3.Text = arrList(2).ToString()
        Label4.Text = arrList(3).ToString()
        Label5.Text = arrList(4).ToString()
        Label6.Text = arrList(5).ToString()
        arrList.Clear()

    End Sub


    Private Sub Empty()
        Label1.Text = &quot;번호1&quot;
        Label2.Text = &quot;번호2&quot;
        Label3.Text = &quot;번호3&quot;
        Label4.Text = &quot;번호4&quot;
        Label5.Text = &quot;번호5&quot;
        Label6.Text = &quot;번호6&quot;
    End Sub

    Private Sub AppOff()
        &#39; 메시지 박스에 물어보기
        Dim result As DialogResult = MessageBox.Show(&quot;정말 종료하시겠습니까?&quot;, &quot;질문&quot;, MessageBoxButtons.YesNo, MessageBoxIcon.Question)

        &#39; 사용자의 응답 확인
        If result = DialogResult.Yes Then
            &#39; 여기에 &quot;예&quot;를 선택했을 때 실행할 코드를 추가할 수 있습니다.
            Debug.WriteLine(&quot;예를 선택하셨습니다.&quot;)
            Close()
        Else
            &#39; 여기에 &quot;아니오&quot;를 선택했을 때 실행할 코드를 추가할 수 있습니다.
            Debug.WriteLine(&quot;아니오를 선택하셨습니다.&quot;)
        End If
    End Sub


End Class


</code></pre>
<hr>
<br>


<h2 id="retrospection">Retrospection</h2>
<hr>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[2023.11.24 TIL(기본강의4)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.11.24-TIL%EA%B8%B0%EB%B3%B8%EA%B0%95%EC%9D%984</link>
            <guid>https://velog.io/@sago_mungcci/2023.11.24-TIL%EA%B8%B0%EB%B3%B8%EA%B0%95%EC%9D%984</guid>
            <pubDate>Sat, 25 Nov 2023 05:30:15 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/efd4435a-bd19-40c9-b40d-0eeb70d173be/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<p>⦁ 간단한 주문앱 만들기</p>
<hr>
<br>

<h2 id="til">TIL</h2>
<p>주문하기</p>
<pre><code class="language-js">Imports System.IO
Imports System.Text

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        &#39;어플리케이션 실행과 동시에 메뉴목록텍스파일 불러와서 리스트 박스에 출력&#39;

        Dim menu As FileIO.TextFieldParser =
            New FileIO.TextFieldParser(&quot;C:\Users\user\Desktop\velog\VBOrederList\상품목록\menu.txt&quot;)

        menu.TextFieldType = FileIO.FieldType.Delimited
        menu.SetDelimiters(&quot;,&quot;)

        While Not menu.EndOfData
            Try
                Dim menuArr As String()
                menuArr = menu.ReadFields()

                ListBox1.Items.Add(menuArr(0) &amp; &quot; || &quot; &amp; menuArr(1))
            Catch ex As Exception
                Console.WriteLine(ex.Message)
            End Try
        End While

    End Sub

    &#39;장바구니에 담기
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        If ListBox1.SelectedItem Is Nothing Then
            MsgBox(&quot;메뉴를 선택해 주세요&quot;)
        Else
            CheckedListBox1.Items.Add(ListBox1.SelectedItem)
        End If





    End Sub
    &#39;장바구니에서 제거
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        If CheckedListBox1.CheckedItems.Count = 0 Then
            MsgBox(&quot;메뉴를 선택해 주세요&quot;)
        Else
            &#39;** 배열을 for each 문이나 for문으로 삭제하면서 발생하는 중에서 발생하는
            &#39;오류 중 인덱스 오류는 처음부터 없애니까 갯수가 줄어들면서 인덱스가 엉킴
            &#39;따라서 배열을 반복문으로 삭제할때는 거꾸로 해줘야 한다 맨뒤부터 차례대로
            &#39;삭제해주어야 한다.
            &#39;중요함 이거 공식수준인데, 순간 기억못해서 당황했다. **
            For i = CheckedListBox1.CheckedItems.Count - 1 To 0 Step -1
                CheckedListBox1.Items.Remove(CheckedListBox1.CheckedItems(i))
            Next




        End If
    End Sub

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

        &#39;주문하기 예외처리
        If CheckedListBox1.CheckedItems.Count = 0 Then
            MsgBox(&quot;주문할 상품을 장바구니에서 체크해 주세요&quot;)
            Return

        End If

        &#39;1.장바구니 상품들을 String 변수에 담아주기
        &#39;vbCrLf = vbNewLine(레거시됨)
        Dim orders As String = Nothing
        For Each item In CheckedListBox1.CheckedItems
            orders += item.ToString() + vbCrLf
        Next

        &#39;2.txt파일로 생성후 주문서 파일에 입력하기
        &#39;텍스트 파일 입력
        Const newTxtFileAdr As String = &quot;C:\Users\user\Desktop\velog\VBOrederList\Orders\요기요주문.txt&quot;
        Dim newTxtFile As IO.FileStream = IO.File.Create(newTxtFileAdr)
        newTxtFile.Close()

        &#39;바이트 배열로 만듬
        &#39;Dim bytes As Byte() = New UTF8Encoding(True).GetBytes(orders)
        Dim writer As IO.StreamWriter

        writer = My.Computer.FileSystem.OpenTextFileWriter(newTxtFileAdr, True)

        &#39;newTxtFile.Write(&quot;넣을 문자열&quot;, &quot;넣을 순서&quot;, &quot;넣을 문자열 갯수&quot;)
        writer.Write(orders)
        writer.Close()

        MsgBox(&quot;주문이 완료되었습니다.&quot;)

        &#39;3.장바구니 상품 초기화
        CheckedListBox1.Items.Clear()


    End Sub
End Class
</code></pre>
<p>주문서 확인 및 히스토리 파일로 옮기기</p>
<pre><code class="language-js">
Imports System.Threading

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        &#39; 어플리케이션이 계속 켜져있는동안 실시간으로 주문서를 확인 할 수있어야 한다.
        &#39; 확인하면 바로 history로 파일을 이동시킨다
        While True

            &#39;스레드 속도 제어
            Threading.Thread.Sleep(500)

            Dim files As String()

            &#39;우리가 해줄게 orders폴더안에 새로운 파일이 생성되었을때 --&gt; 주문이 들어왔을때
            &#39;자동으로 감지해서
            &#39;감지된 파일을 메시지 박스에 출력을 해주고 Orders폴더에서 History폴더로 파일을 옮긴다.
            &#39; 배열과 형변환까지 다해준다.
            files = My.Computer.FileSystem.
            GetFiles(&quot;C:\Users\user\Desktop\velog\VBOrederList\Orders&quot;).ToArray()

            &#39;MsgBox(files.Count)

            &#39;주문서가 들어왔을때 주문서 갯수가 0이 아니면 첫번째의 주문서를 읽어라(가장최근)
            &#39; !=을 &lt;&gt;표현한다.
            If files.Count &lt;&gt; 0 Then

                Dim str As String()

                str = files(0).Split(&quot;\&quot;)

                Dim destinationPath As String = &quot;C:\Users\user\Desktop\velog\VBOrederList\History\&quot; &amp; str(7)
                &#39;맨위의 txt파일(files(0))을 읽어라()
                MsgBox(My.Computer.FileSystem.ReadAllText(files(0)),, str(7))

                If My.Computer.FileSystem.FileExists(destinationPath) Then
                    &#39; 대상 파일이 이미 존재하면 새로운 파일 이름 사용
                    Dim timestamp As String = DateTime.Now.ToString(&quot;yyyyMMddHHmmss&quot;)
                    destinationPath = &quot;C:\Users\user\Desktop\velog\VBOrederList\History\&quot; &amp; timestamp &amp; &quot;_&quot; &amp; str(7)
                End If
                &#39; My.Computer.FileSystem.MoveFile(files(0), &quot;O:\VisualbasicLec\Samples\History\&quot; &amp; str(4), FileIO.UIOption.AllDialogs, FileIO.UICancelOption.DoNothing)
                My.Computer.FileSystem.MoveFile(files(0), destinationPath)

            End If
        End While




    End Sub
End Class


</code></pre>
<hr>
<br>


<h2 id="retrospection">Retrospection</h2>
<ul>
<li>파일 입출력하는 것 참고하면서 익숙해 져야겠다. </li>
</ul>
<hr>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[2023.11.24 TIL(기본강의3.2)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.11.24-TIL%EA%B8%B0%EB%B3%B8%EA%B0%95%EC%9D%983.2</link>
            <guid>https://velog.io/@sago_mungcci/2023.11.24-TIL%EA%B8%B0%EB%B3%B8%EA%B0%95%EC%9D%983.2</guid>
            <pubDate>Fri, 24 Nov 2023 07:23:44 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/7e9915d0-43d1-417e-ac4e-68b0faea1c6a/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<p>⦁ 파일 디렉터리 처리방법</p>
<hr>
<br>

<h2 id="til">TIL</h2>
<p>파일 디렉터리 처리방법</p>
<pre><code class="language-js">
Public Class Form1
    &#39;파일 생성
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        &#39;파일 생성
        &#39;IO.File.Create(&quot;새롭게 생성한 파일을 포함한 경로 즉 경로에 새로운 파일명도 적어줘야한다.&quot;)
        IO.File.Create(&quot;C:\Users\user\Desktop\newVBFile.txt&quot;)
    End Sub

    &#39;파일 삭제
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

        &#39; 삭제할 다이얼로그 오픈이 아니다.
        &#39;If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
        &#39;    &#39;파일 삭제(이거 휴지통에 안들어가고 메모리단에서 그냥 삭제됨)
        &#39;    My.Computer.FileSystem.DeleteFile(OpenFileDialog1.FileName)
        &#39;End If

        &#39;파일 삭제(이거 휴지통에 안들어가고 메모리단에서 그냥 삭제됨)
        &#39; DeletePermanently을 해야 다이얼로그가 나타난다.(SendToRecycleBin으로 하면 다이얼로그가 안나옴)
        My.Computer.FileSystem.DeleteFile(&quot;C:\Users\user\Desktop\newVBFile.txt&quot;,
                                          FileIO.UIOption.AllDialogs,
                                          FileIO.RecycleOption.DeletePermanently,
                                          FileIO.UICancelOption.DoNothing)

    End Sub

    &#39;파일 이동
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        &#39;파일 이동
        &#39;My.Computer.FileSystem.MoveDirectory(&quot;이동시키고 싶은 파일&quot;, &quot;이동하려는 경로 + 이동시키려는 파일명&quot;)
        &#39;리눅스(우분투)와 마찬가지로 파일을 이동시킬떄 파일명을 바꿔서 이동시키면 파일명이 바퀴는데
        &#39;여기서도 마찬가지이다.
        My.Computer.FileSystem.MoveFile(&quot;C:\Users\user\Desktop\newVBFile.txt&quot;, &quot;C:\Users\user\Desktop\velog\newVBFile1.txt&quot;)
    End Sub

    &#39;파일복사
    &#39;My.Computer.FileSystem.CopyFile(&quot;이동시키고 싶은 파일&quot;, &quot;이동하려는 경로 + 이동시키려는 파일명&quot;,덮어쓰기 여부(true || false))
    &#39;리눅스(우분투)와 마찬가지로 파일을 이동시킬떄 파일명을 바꿔서 이동시키면 파일명이 바퀴는데
    &#39;여기서도 마찬가지이다.
    &#39;기본값은 false (덮어쓰지 않음.) --&gt; false를 사용하기
    &#39;true로 하면 덮어씀
    &#39;MS 계열의 언어를 쓰면 MS OS의 유틸리티를 활용하기 쉽다.
    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
        My.Computer.FileSystem.CopyFile(&quot;C:\Users\user\Desktop\newVBFile.txt&quot;,
                                        &quot;C:\Users\user\Desktop\velog\newVBFile1.txt&quot;,
                                        FileIO.UIOption.AllDialogs,
                                        FileIO.UICancelOption.DoNothing)
    End Sub

    &#39;파일명 변경
    Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
        &#39;My.Computer.FileSystem.RenameFile(&quot;변경할 기존 파일 경로+파일명&quot;,
        &#39;&quot; 새롭게 변경할 파일 명&quot;)
        My.Computer.FileSystem.RenameFile(&quot;C:\Users\user\Desktop\newVBFile.txt&quot;,
                                          &quot;newVBFile1.txt&quot;)

    End Sub

    &#39;폴더 생성
    Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
        &#39;My.Computer.FileSystem.CreateDirectory(&quot;폴더를 생성할 경로 + 폴더명&quot;)
        My.Computer.FileSystem.CreateDirectory(&quot;C:\Users\user\Desktop\velog\VBtest&quot;)
    End Sub

    &#39;폴더 복사
    Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click
        &#39;My.Computer.FileSystem.CopyDirectory(&quot;원래 폴더 경로 +폴더명&quot;, &quot;복사하려는 경로 + 복사하려는 폴더명 , 덮어쓰기 여부(true || false))
        My.Computer.FileSystem.CopyDirectory(&quot;C:\Users\user\Desktop\velog\VBtest&quot;, &quot;C:\Users\user\Desktop\VBtest1&quot;)
    End Sub

    &#39;폴더 삭제
    &#39; 파일 삭제와 동일
    Private Sub Button8_Click(sender As Object, e As EventArgs) Handles Button8.Click
        &#39;사용법 1
        &#39;My.Computer.FileSystem.DeleteDirectory(&quot;C:\Users\user\Desktop\velog\VBtest&quot;,
        &#39;                                  FileIO.UIOption.AllDialogs,
        &#39;                                  FileIO.RecycleOption.DeletePermanently,
        &#39;                                  FileIO.UICancelOption.DoNothing)

        &#39; FileIO.DeleteDirectoryOption.DeleteAllContents : 해당 폴더 내용 전체 삭제
        &#39;FileIO.DeleteDirectoryOption.ThrowIfDirectoryNonEmpty : 해당 폴더가 비어 있지 않으면 경고
        &#39;사용법 2

        Try
            My.Computer.FileSystem.DeleteDirectory(&quot;C:\Users\user\Desktop\velog\VBtest&quot;,
                                          FileIO.DeleteDirectoryOption.ThrowIfDirectoryNonEmpty)
        Catch ex As IO.IOException &#39;해당 메서드가 반환하는 예외처리와 동일해야함. 
            &#39;위의 예외가 실행 되었을때 실행 하는 구문
            MsgBox(ex.Message,, &quot;주의해주세요!&quot;)
            Return
        End Try

    End Sub

    &#39;폴더명 변경
    Private Sub Button9_Click(sender As Object, e As EventArgs) Handles Button9.Click
        My.Computer.FileSystem.RenameDirectory(&quot;C:\Users\user\Desktop\velog\VBtest&quot;, &quot;VBtest1&quot;)
    End Sub

    &#39;파일리스트 조회
    Private Sub Button10_Click(sender As Object, e As EventArgs) Handles Button10.Click
        Dim fileArr As String()

        &#39;My.Computer.FileSystem.GetFiles(&quot;해당 폴더의 경로&quot;)
        fileArr = My.Computer.FileSystem.GetFiles(&quot;C:\Users\user\Desktop\velog\VBtest&quot;).ToArray()

        For Each item As String In fileArr

            ListBox1.Items.Add(item)

        Next




    End Sub

    &#39;폴더리스트 조회
    Private Sub Button11_Click(sender As Object, e As EventArgs) Handles Button11.Click
        Dim folderArr As String()

        folderArr = My.Computer.FileSystem.GetDirectories(&quot;C:\Users\user\Desktop\velog\VBtest&quot;).ToArray()

        For Each item As String In folderArr
            ListBox2.Items.Add(item)
        Next


    End Sub


    &#39; 폴더내 특정 파일 정보 조회
    Private Sub Button12_Click(sender As Object, e As EventArgs) Handles Button12.Click
        Dim testFileInfo As IO.FileInfo
        testFileInfo = My.Computer.FileSystem.GetFileInfo(&quot;C:\Users\user\Desktop\velog\VBtest\newVBFile3.txt&quot;)

        MsgBox(testFileInfo.Name)
        MsgBox(testFileInfo.FullName)
        MsgBox(testFileInfo.DirectoryName)
        MsgBox(testFileInfo.Exists)
        MsgBox(testFileInfo.Length)


    End Sub
End Class


</code></pre>
<hr>
<br>


<h2 id="retrospection">Retrospection</h2>
<hr>
<br>
]]></description>
        </item>
        <item>
            <title><![CDATA[2023.11.24 TIL(기본강의3.1)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.11.24-TIL%EA%B8%B0%EB%B3%B8%EA%B0%95%EC%9D%983.1</link>
            <guid>https://velog.io/@sago_mungcci/2023.11.24-TIL%EA%B8%B0%EB%B3%B8%EA%B0%95%EC%9D%983.1</guid>
            <pubDate>Fri, 24 Nov 2023 07:21:15 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/d784bb69-d073-483e-a369-9369827ed2f6/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<p>⦁파일입력</p>
<hr>
<br>

<h2 id="til">TIL</h2>
<p>파일입력</p>
<pre><code class="language-java">Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click


        &#39;true : 기존의 텍스트 내용 뒤에 추가할 문자열이 들어감
        &#39;false : 기존의 텍스트 내용을 삭제후 추가한 문자열이 들어감
        &#39;****기본값은 false이다!!! 주의하기!!!!!!****
        &#39;My.Computer.FileSystem.WriteAllText(&quot;경로&quot;, &quot;추가할 문자열&quot;, &quot;true || false&quot;)
        &#39;My.Computer.FileSystem.WriteAllText(&quot;C:\Users\user\Desktop\vbtest2.txt&quot;,
        &#39;                                    &quot;새로운 텍스트입니다.&quot; &amp; vbCrLf,
        &#39;                                    True)
        &#39;OpenFileDialog1.ShowDialog()

        If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
            &#39;OpenFileDialog1.FileName : OpenFileDialog1.ShowDialog()에서 선택한 파일의 경로
            My.Computer.FileSystem.WriteAllText(OpenFileDialog1.FileName,
                                                &quot;NEW 텍스트입니다.&quot; &amp; vbCrLf,
                                                True)
        End If



    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim fileStream As IO.StreamWriter

        If OpenFileDialog1.ShowDialog() = DialogResult.OK Then

            &#39;fileStream = My.Computer.FileSystem.OpenTextFileWriter(&quot;경로&quot;,&quot;true || false&quot;)
            fileStream = My.Computer.FileSystem.OpenTextFileWriter(OpenFileDialog1.FileName, True)
            fileStream.WriteLine(&quot;fileStream입니다.&quot;)
            &#39;항상 fileStream을 사용하면 close해주기
            fileStream.Close()

        End If

    End Sub
End Class

</code></pre>
<hr>
<br>


<h2 id="retrospection">Retrospection</h2>
<hr>
<br>


]]></description>
        </item>
        <item>
            <title><![CDATA[2023.11.24 TIL(VB기본강의3)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.11.24-TILVB%EA%B8%B0%EB%B3%B8%EA%B0%95%EC%9D%983</link>
            <guid>https://velog.io/@sago_mungcci/2023.11.24-TILVB%EA%B8%B0%EB%B3%B8%EA%B0%95%EC%9D%983</guid>
            <pubDate>Fri, 24 Nov 2023 02:28:49 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/6c02472a-27c8-4af6-bfe0-27b202c96805/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<p>⦁ 파일 입출력</p>
<hr>
<br>

<h2 id="til">TIL</h2>
<p>파일 출력1</p>
<pre><code class="language-java">Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        &#39;파싱할때 구분자로 나누어서 출력(문장을 편집하고 싶을때 사용)
        &#39;FileIO.TextFieldParser클래스의 생성자 생성
        &#39;Dim parsindTxt As FileIO.TextFieldParser
        &#39;parsindTxt = New FileIO.TextFieldParser(&quot;C:\Users\user\Desktop\vbTest.txt&quot;)
        Dim parsindTxt As FileIO.TextFieldParser = New FileIO.TextFieldParser(&quot;C:\Users\user\Desktop\vbTest.txt&quot;)
        &#39;Delimited: 파일을 읽어올때 한줄당 &quot;특정문자&quot;를 기준으로 문장을 구분할때 사용
        &#39;FixedWidth : 파일을 읽어올때 한줄당 &quot;문자갯수&quot;만 읽어서 출력한다.
        &#39;parsindTxt.TextFieldType = FileIO.FieldType.Delimited
        &#39;parsindTxt.SetDelimiters(&quot;/&quot;)
        parsindTxt.TextFieldType = FileIO.FieldType.FixedWidth
        &#39;한줄에 있는 처음 두글자, 그다음 3글자 -1은 나머지 모든 문장을 출력
        &#39; -1자체는 한줄에 있는 모든 문장 출력
        parsindTxt.SetFieldWidths(2, 3, -1)

        &#39;EndOfData : 읽어올 텍스트파일의 끝
        While Not parsindTxt.EndOfData
            &#39;Dim currentTxt As String()
            &#39;문자열 배열을 선언합니다.
            &#39;이 경우, currentTxt는 문자열의 배열을 나타내는 변수가 됩니다.
            &#39;이 배열은 여러 문자열을 저장할 수 있는 구조체입니다.

            &#39;Dim currentTxt As String
            &#39;단일 문자열을 저장하는 변수를 선언합니다.
            &#39;이 경우, currentTxt는 단일 문자열을 나타내는 변수가 됩니다.
            Dim currentTxtArr As String()
            &#39;TextFieldParser는 기본적으로 한줄씩 읽어온다.
            currentTxtArr = parsindTxt.ReadFields()

            Dim currentTxt As String
            For Each currentTxt In currentTxtArr
                Label1.Text = currentTxt
                MsgBox(currentTxt,, &quot;Title&quot;)
            Next

        End While



        &#39;Dim sentence As String
        &#39;PC 내부의 텍스트파일을 읽어서 스트링변수에 담음
        &#39;sentence = My.Computer.FileSystem.ReadAllText(&quot;C:\Users\user\Desktop\vbTest.txt&quot;)
        &#39;Label1.Text = sentence
        &#39;MsgBox(sentence,, &quot;Title&quot;)

    End Sub
End Class

</code></pre>
<p>파일 출력2</p>
<pre><code class="language-java">
Public Class Form1

    Public Class Product
        Public pName As String
        Public pNum As String

        &#39; 생성자 정의
        &#39; 자바와 C#과는 달리 클래스를 생성해도 기본 생성자를 따로 만들어주지 않는다.
        &#39; 생성자 선언 코딩도 전혀 다르다.
        Public Sub New()

        End Sub

        Public Sub New(pName As String, pNum As String)
            Me.pName = pName
            Me.pNum = pNum
        End Sub


    End Class

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        &#39;클래스 객체 생성하는 게 궁금해서 그냥 만들어봄
        &#39;Dim product As Product = New Product(&quot;자동차&quot;, &quot;123&quot;)

        Dim chosenFormat As Integer() = {3, 4, 3, 1}
        Dim hyundaiFormat As Integer() = {3, 4, 12, 1}

        Dim txtParser As FileIO.TextFieldParser = New FileIO.TextFieldParser(&quot;C:\Users\user\Desktop\vbtest2.txt&quot;)
        txtParser.TextFieldType = FileIO.FieldType.FixedWidth
        &#39;txtParser.SetFieldWidths()

        &#39;ReadFields()가 배열로 반환하기 때문이다.
        Dim lineData As String()

        While Not txtParser.EndOfData
            &#39;첫글자가 조선, 현대인지에 따라서 문자수를 자라서 출력한다.
            &#39;해당 파일의 첫글자가 조선인지 현대인지 알수 있는 PeekChars(숫자)함수를 사용한다.
            &#39;해당 파일의 글자를 앞에서부터 지정한 숫자만큼 읽어 온다.
            Dim twoLetter As String = txtParser.PeekChars(2)

            &#39;twoLetter.eqauls(&quot;조선&quot;)을
            &#39;VB에서 String.Compare(twoLetter, &quot;조선&quot;) 사용하는데
            &#39;같다면 0 아니면 0이 아닌 숫자를 반환한다.
            If String.Compare(twoLetter, &quot;조선&quot;) = 0 Then

                txtParser.SetFieldWidths(chosenFormat)

            ElseIf String.Compare(twoLetter, &quot;현대&quot;) = 0 Then

                txtParser.SetFieldWidths(hyundaiFormat)

            End If
            &#39;첫줄이 끝나면 다음줄에 커서를 가져다가 시작함 
            lineData = txtParser.ReadFields()

            Dim sentence As String = &quot;시대: &quot; &amp; lineData(0) &amp; vbCrLf &amp;
                                     &quot;이름: &quot; &amp; lineData(1) &amp; vbCrLf &amp;
                                     &quot;연락처: &quot; &amp; lineData(2) &amp; vbCrLf &amp;
                                     &quot;성별: &quot; &amp; lineData(3) &amp; vbCrLf
            MsgBox(sentence)
        End While

        &#39;Label1.Text = txtParser.ToString()

    End Sub
End Class


</code></pre>
<p>파일 출력3</p>
<pre><code class="language-java">Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        &#39;StreamReader: 한줄의 문장을 처음부터 끝까지 출력
        Dim txtReader As IO.StreamReader
        txtReader = My.Computer.FileSystem.OpenTextFileReader(&quot;C:\Users\user\Desktop\vbtest2.txt&quot;)

        While Not txtReader.EndOfStream

            MsgBox(txtReader.ReadLine())

        End While

        &#39;StreamReader는 파일을 실행하고 계속 메모리에 올려놓기때문에 
        &#39;만약 클로즈를 안하면 어플리케이션을 종료하기 전까지 해당 txt파일을 수정할수없다.
        &#39;arrayList와 비슷
        txtReader.Close()


    End Sub
End Class
</code></pre>
<hr>
<br>


<h2 id="retrospection">Retrospection</h2>
<hr>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[2023.11.22 TIL(VB강의2)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.11.22-TILVB%EA%B0%95%EC%9D%982</link>
            <guid>https://velog.io/@sago_mungcci/2023.11.22-TILVB%EA%B0%95%EC%9D%982</guid>
            <pubDate>Wed, 22 Nov 2023 05:57:27 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/e4b82cf5-2e1a-4987-a02e-99d36809cd37/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<p>⦁ 간단한 출력문
⦁ 계산기</p>
<hr>
<br>

<h2 id="til">TIL</h2>
<pre><code class="language-java">Imports System.Windows.Forms.VisualStyles.VisualStyleElement

Public Class Form1
    &#39;변수 선언하는 방법: Dim 변수명 자료형을 As 뒤에 선언한다.
    Dim A As Integer
    Dim B As String

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        SetControl()
    End Sub

    Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
        &#39;SetControl()
        &#39;SetEvent()
    End Sub

    Private Sub SetControl()
        &#39;MessageBox.Show(&quot;setControl&quot;)
        txtInput.MaxLength = 1


    End Sub

    Private Sub SetEvent()
        &#39;MessageBox.Show(&quot;setEvent&quot;)

    End Sub


    &#39;AndAlso는 VB.NET에서 사용되는 논리 연산자 중 하나입니다.
    &#39;이 연산자는 논리 And 연산을 수행하며,
    &#39;첫 번째 조건이 거짓이면 두 번째 조건을 평가하지 않습니다.

    &#39;간단히 말하면, 첫 번째 조건이 거짓이면 두 번째 조건을 확인하지 않고
    &#39;전체 표현식을 거짓으로 평가합니다.
    &#39;이는 두 조건 중 하나라도 거짓이면 전체 표현식이 거짓이라는 논리를 반영합니다.
    &#39;이를 &quot;short-circuit&quot; 논리 연산이라고도 합니다

    &#39;숫자만 입력되게 해줌
    Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtInput.KeyPress
        &#39; 입력된 키가 숫자인지 확인
        If Not Char.IsDigit(e.KeyChar) AndAlso Not Char.IsControl(e.KeyChar) Then

            MessageBox.Show(&quot;숫자를 입력해주세요&quot;)
            &#39; 숫자가 아니면 입력을 무시
            e.Handled = True

        ElseIf e.KeyChar = &quot;0&quot; Or e.KeyChar = &quot;6&quot; Or e.KeyChar = &quot;7&quot; Or e.KeyChar = &quot;8&quot; Or e.KeyChar = &quot;9&quot; AndAlso txtInput.Text.Length = 0 Then
            MessageBox.Show(&quot;1~5만 입력해주세요&quot;)
            &#39; 첫 번째 자리에 0은 허용하지 않음
            e.Handled = True

        End If
    End Sub

    Private Sub txtInput_TextChanged(sender As Object, e As EventArgs) Handles txtInput.TextChanged
        If txtInput.Text = Nothing Then

        Else
            A = Integer.Parse(txtInput.Text)
        End If


    End Sub

    Private Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click

        Label2.Text = Message(A)

    End Sub

    Private Function Message(A As Integer) As String

        If A = 1 Then
            B = &quot;1을 선택하셨습니다.&quot;
        End If

        If A = 2 Then
            B = &quot;2를 선택하셨습니다.&quot;
        End If

        If A = 3 Then
            B = &quot;3을 선택하셨습니다.&quot;
        End If

        If A = 4 Then
            B = &quot;4를 선택하셨습니다.&quot;
        End If

        If A = 5 Then
            B = &quot;5를 선택하셨습니다.&quot;
        End If

        Return B

    End Function

End Class

</code></pre>
<p>계산기</p>
<pre><code class="language-java">
Public Class Form1

    &#39;label textalign -&gt; 라벨의 위치를 정할수 있다.
    &#39;Form 속성의 opacity -&gt; form 대화상자의 투명도를 조절할수 있다.

    &#39;Enum 클래스 선언
    &#39;변수들의 번호는 위에서부터 0,1,2가 된다.
    Enum State
        EndCalc
        DuringCalc
        Inputting
    End Enum

    Enum Sign
        None
        Division
        Multipication
        Subtraction
        Addition
    End Enum


    &#39;연산 부호
    Dim curSign As Integer = Sign.None

    &#39;0 = 계산이 끝난 상태
    &#39;1 = 계산 중
    &#39;2 = 숫자 입력 중
    &#39;아래와 같이 As 뒤에 enum클래스를 선언하면 숫자가 아니라 해당 번호에
    &#39;해당하는 value값이 나온다.
    Dim curState As State = State.EndCalc

    Dim num1 As Integer
    Dim num2 As Integer

    &#39;boolean의 기본값은 false이다!!!!!
    Dim isNum1 As Boolean
    Dim isNum2 As Boolean

    &#39;숫자입력 메서드
    Private Sub btn_Click(sender As Object, e As EventArgs) Handles btn0.Click, btn1.Click, btn2.Click, btn3.Click, btn4.Click, btn5.Click, btn6.Click, btn7.Click, btn8.Click, btn9.Click

        &#39;Label1.Text = sender.Name

        If curState = 0 Then
            curSign = 0
            curState = 0
            num1 = 0
            num2 = 0
            isNum1 = False
            isNum2 = False
            lblMain.Text = Nothing
            lblSign.Text = Nothing
        ElseIf curState = 1 Then &#39;계산중
            lblMain.Text = Nothing
        End If

        Select Case sender.Name
            Case btn0.Name
                lblMain.Text += &quot;0&quot;
            Case btn1.Name
                lblMain.Text += &quot;1&quot;
            Case btn2.Name
                lblMain.Text += &quot;2&quot;
            Case btn3.Name
                lblMain.Text += &quot;3&quot;
            Case btn4.Name
                lblMain.Text += &quot;4&quot;
            Case btn5.Name
                lblMain.Text += &quot;5&quot;
            Case btn6.Name
                lblMain.Text += &quot;6&quot;
            Case btn7.Name
                lblMain.Text += &quot;7&quot;
            Case btn8.Name
                lblMain.Text += &quot;8&quot;
            Case btn9.Name
                lblMain.Text += &quot;9&quot;
            Case Else

        End Select

        curState = 2
        lblCurState.Text = curState.ToString()
    End Sub
    &#39;연산 메서드
    Private Sub btnCulculator_Click(sender As Object, e As EventArgs) Handles btnDivision.Click, btnMultipication.Click, btnSubtraction.Click, btnAddition.Click
        &#39;(임시)
        &#39;1= 나누기 버튼 클릭됩
        &#39;2= 곱하기 버튼 클릭됩
        &#39;3= 빼기 버튼 클릭됩
        &#39;4= 더하기 버튼 클릭됩

        If isNum1 = False Then
            num1 = Val(lblMain.Text)
            isNum1 = True
        ElseIf isNum2 = False Then
            num2 = Val(lblMain.Text)
            isNum2 = True
        End If

        Select Case sender.Name
            Case btnDivision.Name
                curSign = 1
                lblSign.Text += &quot;÷&quot;

            Case btnMultipication.Name
                curSign = 2
                lblSign.Text += &quot;×&quot;

            Case btnSubtraction.Name
                curSign = 3
                lblSign.Text += &quot;-&quot;

            Case btnAddition.Name
                curSign = 4
                lblSign.Text += &quot;+&quot;

            Case Else

        End Select

        curState = 1
        lblCurState.Text = curState.ToString()
    End Sub

    &#39;연산결과 출력메서드
    Private Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
        &#39;일단 계산하는 숫자는 1과 2로 고정(임시로)

        &#39;Val함수 : 문자열에서 문자를 만나기 전까지 숫자를 뽑아서 Interger형으로 변환시켜준다. 
        &#39;공백이 있어도 상관없다.
        &#39;1 2 안녕하세요  3 4 -&gt; 12출력
        If isNum1 = False Then
            num1 = Val(lblMain.Text)
            isNum1 = True
        ElseIf isNum2 = False Then
            num2 = Val(lblMain.Text)
            isNum2 = True
        End If

        Select Case curSign
            Case 1
                &#39;lblMain.Text = 1 / 2
                num1 = num1 / num2
            Case 2
                &#39;lblMain.Text = 1 * 2
                num1 = num1 * num2
            Case 3
                &#39;lblMain.Text = 1 - 2
                num1 = num1 - num2
            Case 4
                &#39;lblMain.Text = 1 + 2
                num1 = num1 + num2
            Case Else
                Debug.WriteLine(&quot;연산 선택 안됨&quot;)

        End Select

        lblMain.Text = num1

        curState = 0
        lblCurState.Text = curState.ToString()

    End Sub
    &#39;클리어메서드
    Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
        curSign = 0
        curState = 0
        num1 = 0
        num2 = 0
        isNum1 = False
        isNum2 = False
        lblMain.Text = Nothing
        lblSign.Text = Nothing

    End Sub
    &#39;벡스페이스 메서드
    Private Sub btnBackSpace_Click(sender As Object, e As EventArgs) Handles btnBackSpace.Click
        If lblMain.Text.Length &gt; 0 Then
            &#39;Remove함수 첫번째 매개변수 : 삭제를 할 첫번째 위치(length는 시작이 0이다.)
            &#39;Remove함수 두번째 매개변수 : 삭제를 할 텍스트 갯수
            lblMain.Text = lblMain.Text.Remove(lblMain.Text.Length - 1, 1)

        End If
    End Sub
End Class


</code></pre>
<hr>
<br>


<h2 id="retrospection">Retrospection</h2>
<ul>
<li><p>변수명 선언에서부터 if문, select case(switch문) 반환하는 형식의 메서드 등등 낮설다. </p>
</li>
<li><p>항상 분할과 정복방법으로 생각하자</p>
<ul>
<li>계산기 : 계산하는 것이 목적 </li>
<li>어떻게 사용하나? --&gt; 숫자 입력, 연산, 결과도출</li>
<li>각가의 계산상태 구분 및 연산구분(+,-,*,/)을 구분해서 코드화시키자.</li>
</ul>
</li>
</ul>
<hr>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[2023.11.21 TIL(VB강의)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.11.21-TILVB%EA%B0%95%EC%9D%98</link>
            <guid>https://velog.io/@sago_mungcci/2023.11.21-TILVB%EA%B0%95%EC%9D%98</guid>
            <pubDate>Tue, 21 Nov 2023 09:53:12 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/eca4a9d7-3963-42e5-88a8-5c8222c48ee7/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<p>⦁ 저번주에 이직하는 회사에 최종합격했다.(MES관련 회사)
⦁ VB로 많이 구성되어 있다고 하셨다.
⦁ 기초는 먼저 공부해봐야 될것 같아서 유료강의를 결제하였다.</p>
<hr>
<br>
## TIL


<pre><code class="language-java">Public Class Form1
    &#39;vb에서 ;안쓴다.
    &#39;if구문도 Java, C#과 다르다
    &#39;테이블 레이아웃으로 구획을 나누면 나눈 구획에는 하나의 컨트롤만 들어갈수 있다.
    &#39;flowLayoutpannel
    &#39;버튼 autosize : 버튼이름이 길때 알아서 버튼의 크기가 조정된다.
    &#39;openFileDialog 필터 속성 JPEG Files (*.jpg)|*.jpg|PNG Files (*.png)|*.png|BMP Files (*.bmp)|*.bmp|All files (*.*)|*.*
    &#39;Nothing = null vb에서 null을 Nothing으로 사용한다.

    &#39;2023.11.21 / 박민준 / strech 체크박스 생성
    Private Sub CheckBoxStrech_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBoxStrech.CheckedChanged
        &#39; 실행시킨 이미지가 대화상자에 맞지 않을때 이 체크박스를 누르면 알아서 이미지가
        &#39; 맞춰지게 함.
        If CheckBoxStrech.Checked Then
            PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
        Else
            PictureBox1.SizeMode = PictureBoxSizeMode.Normal
        End If
    End Sub

    &#39;2023.11.21 / 사고뭉치 / 그림 표시
    Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
        &#39; 그림을 입력하세요라는 대화상자가 열리고 확인을 눌렀을때
        If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
            &#39; 그림이미지 이름과 확장자를 가지고 파일을 실행시킨다.
            PictureBox1.Load(OpenFileDialog1.FileName)
        End If
    End Sub
    &#39;2023.11.21 / 사고뭉치 / 그림 삭제
    &#39;Nothing = null vb에서 null을 Nothing으로 사용한다.
    Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
        PictureBox1.Image = Nothing
    End Sub

    &#39;2023.11.21 / 사고뭉치 / 배경색 변경
    Private Sub btnSetColor_Click(sender As Object, e As EventArgs) Handles btnSetColor.Click
        If ColorDialog1.ShowDialog() = DialogResult.OK Then
            PictureBox1.BackColor = ColorDialog1.Color
            &#39;아래와 같이 응용이 가능하다.
            &#39;btnClear.BackColor = ColorDialog1.Color 
        End If
    End Sub

    &#39;2023.11.21 / 사고뭉치 / 닫기
    Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
        Close()
    End Sub
End Class

</code></pre>
<hr>
<br>


<h2 id="retrospection">Retrospection</h2>
<ul>
<li>java, C#과 비교해서 객체지향이라는 개념만 동일할뿐 코드나 언어가 상당히 많이 다르다.</li>
</ul>
<hr>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[2023.09.15(React JS필기 정리)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.09.15React-JS%ED%95%84%EA%B8%B0-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@sago_mungcci/2023.09.15React-JS%ED%95%84%EA%B8%B0-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 15 Sep 2023 10:18:37 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/23fb5dcf-3b24-4df6-bede-e96643cd0a70/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<p>⦁ styled component</p>
<hr>
<br>

<h2 id="til">TIL</h2>
<ul>
<li>styled component<pre><code class="language-js">import React from &#39;react&#39;
// 스타일컴포넌트 설치
// npm i styled-component
//styled component css 적용 시 자동완성은
//vscode-styled-components 익스텐션을 받으면 됨
import styled from &#39;styled-components&#39;
</code></pre>
</li>
</ul>
<p>// styled component 사용법 잘보기 styled. 뒤에 오는 것은 html 태그가 와야된다.
// 그다음 ``안에는 css코드가 와야한다.
const Father = styled.div<code>display: flex;</code>
const BoxOne = styled.div<code>background-color: teal;
  width: 100px;
  height: 100px;</code></p>
<p>const BoxTwo = styled.div<code>background-color: tomato;
  width: 100px;
  height: 100px;</code>
const Text = styled.span<code>color: white;</code></p>
<p>const Styledcomponent = () =&gt; {
  return (
    <Father>
      <BoxOne>
        <Text>Hello!</Text>
      </BoxOne>
      <BoxTwo></BoxTwo>
    </Father>
  )
}</p>
<p>export default Styledcomponent</p>
<p>```</p>
<hr>
<br>


<h2 id="retrospection">Retrospection</h2>
<ul>
<li><p>포트폴리오를 만들고 이걸 보니 이론적으로 css파일을 따로 만들지 않고도 FE를 구현 가능하지 않을까?</p>
</li>
<li><p>아..... 반응형때문에 안될수도 있겠다...</p>
</li>
</ul>
<hr>
<br>

<h2 id="tommorrow-do-list">Tommorrow do list</h2>
<hr>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[2023.09.15(포트폴리오 템플릿 제작)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.09.15%ED%8F%AC%ED%8A%B8%ED%8F%B4%EB%A6%AC%EC%98%A4-%ED%85%9C%ED%94%8C-%EC%A0%9C%EC%9E%91</link>
            <guid>https://velog.io/@sago_mungcci/2023.09.15%ED%8F%AC%ED%8A%B8%ED%8F%B4%EB%A6%AC%EC%98%A4-%ED%85%9C%ED%94%8C-%EC%A0%9C%EC%9E%91</guid>
            <pubDate>Fri, 15 Sep 2023 09:11:19 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/fd9814eb-adc3-41f3-8075-cf2cc7465aaa/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<p>PROJECT 소개 자신을 소개하고 결과물을 보여줄 수 있는 포트폴리오 웹페이지를 구현하였습니다.</p>
<p>노마드 코더님의 ReactJS로 영화 웹 서비스 만들기 강의 후 전체적으로 어떻게 ReactJS 구현되는 지를 단일 페이지를 정복-분할 방식으로 이해하고 싶어서 고민 중 포트폴리오를 웹을 구축해보면 좋을것 같아서 같이 공부했습니다.</p>
<p>노마드 코더님의 강의를 들으면서 ReactJS를 이해하는 데 큰 도움이 되었으며 특히 FE의 기초를 다질 수 있어서 너무 좋았습니다.</p>
<p>🗓️ 작업기간 : 2023.09.01-2023.09.15</p>
<p>🙋 참여인원 : 1명</p>
<p>📘 주요업무 : 포트폴리오 관리</p>
<hr>
<br>

<h2 id="til">TIL</h2>
<p>Sago_Muncci&#39;s Portfolio : <a href="https://pmjn1025.github.io/My_Portfolio/">https://pmjn1025.github.io/My_Portfolio/</a></p>
<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/18aa5c42-97aa-47bb-bc38-55b631b0b44f/image.png" alt="">
<img src="https://velog.velcdn.com/images/sago_mungcci/post/843ba081-6859-4450-89d4-7965ae266d34/image.png" alt="">
<img src="https://velog.velcdn.com/images/sago_mungcci/post/43737898-591b-438c-85f0-486fcb876261/image.png" alt="">
<img src="https://velog.velcdn.com/images/sago_mungcci/post/700d42e6-9582-44a9-ada3-08b613033883/image.png" alt="">
<img src="https://velog.velcdn.com/images/sago_mungcci/post/5343cdac-a36e-496b-ace7-b1bbcfb81709/image.png" alt=""></p>
<hr>
<br>


<h2 id="retrospection">Retrospection</h2>
<p>ReactJs를 이용하여 어떻게 FE를 구축하는지 전체적인 맥락을 잡았을 뿐 ReactJS에서 사용하는 routes 및 라이브러리에 대해서 좀 더 공부해야겠다는 생각을 했습니다.</p>
<p>특히 CSS가 엄청 중요하다는 사실을 알게되었습니다. 따라서 CSS에 대한 지식도 같이 보완해야 된다고 생각합니다.</p>
<hr>
<br>

<h2 id="tommorrow-do-list">Tommorrow do list</h2>
<ul>
<li>노마드 코더 React JS 마스터클래스 수강시작!</li>
</ul>
<hr>
<br>
]]></description>
        </item>
        <item>
            <title><![CDATA[2023.09.11~13(React JS필기 정리)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.09.1113React-JS%ED%95%84%EA%B8%B0-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@sago_mungcci/2023.09.1113React-JS%ED%95%84%EA%B8%B0-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Thu, 14 Sep 2023 00:56:44 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/60abbc0c-c73a-40bc-a03d-7e849337ab3b/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<ul>
<li>Nomad Coder - ReactJS로 영화 웹 서비스 만들기</li>
<li>coinAppChallenge</li>
<li>movieApp 만들기<ul>
<li>route</li>
</ul>
</li>
</ul>
<hr>
<br>

<h2 id="til">TIL</h2>
<p>CoinTrackerApp.js</p>
<pre><code class="language-js">import { useEffect, useState } from &#39;react&#39;

function CoinTrackerApp() {
  const [loading, setLoading] = useState(true)
  const [coins, setCoins] = useState([])
  useEffect(() =&gt; {
    fetch(&#39;https://api.coinpaprika.com/v1/tickers?limit=100&#39;)
      //fetch(&#39;https://api.coinpaprika.com/v1/tickers&#39;)
      .then((response) =&gt; response.json())
      .then((json) =&gt; {
        console.log(json)
        setCoins(json)
        setLoading(false)
      })
  }, [])
  return (
    &lt;div&gt;
      &lt;h1&gt;The Coins! {loading ? &#39;&#39; : `(${coins.length})`}&lt;/h1&gt;
      {loading ? &lt;strong&gt;Loding...&lt;/strong&gt; : null}
      &lt;ul&gt;
        {coins.map((coins) =&gt; (
          &lt;li key={coins.id}&gt;
            {coins.name}({coins.symbol}) : ${coins.quotes.USD.price}
            &lt;span&gt; &lt;/span&gt;
            Coin Rank : {coins.rank}
          &lt;/li&gt;
        ))}
      &lt;/ul&gt;
    &lt;/div&gt;
  )
}

export default CoinTrackerApp
</code></pre>
<hr>
<p>coninTrackerChallengeApp.js</p>
<pre><code class="language-js">import { useEffect, useState } from &#39;react&#39;
import coinChallenge from &#39;./CoinChallenge.module.css&#39;

function CoinTrackerChallengeApp() {
  const [loading, setLoading] = useState(true)
  const [coins, setCoins] = useState([])
  const [limit, setLimit] = useState(100) // `https://api.coinpaprika.com/v1/tickers?limit=${limit}&amp;&amp;quotes=KRW`
  useEffect(() =&gt; {
    // const interval = setInterval(() =&gt; {
    //   fetch(`https://api.coinpaprika.com/v1/tickers?limit=${limit}&amp;&amp;quotes=KRW`)
    //     .then((response) =&gt; response.json())
    //     .then((json) =&gt; {
    //       console.log(json)
    //       setCoins(json)
    //       setLoading(false)
    //       console.log(&#39;1&#39;)
    //     })
    // }, 1000)
    // return () =&gt; clearInterval(interval)
    fetch(`https://api.coinpaprika.com/v1/tickers?limit=${limit}&amp;&amp;quotes=KRW`)
      .then((response) =&gt; response.json())
      .then((json) =&gt; {
        console.log(json)
        setCoins(json)
        setLoading(false)
        console.log(&#39;1&#39;)
      })
  }, [limit])

  const onClick = () =&gt; {
    setLimit((current) =&gt; current + 100)
  }

  const onChange = () =&gt; {}

  return (
    &lt;div&gt;
      &lt;div className={coinChallenge.title}&gt;
        &lt;h1&gt;Cryptocurrency in real time!&lt;/h1&gt;
      &lt;/div&gt;
      &lt;div className={coinChallenge.search}&gt;
        &lt;form&gt;
          &lt;input
            type=&quot;text&quot;
            placeholder=&quot;search Cryptocurrency&quot;
            onChange={onChange}
          &gt;&lt;/input&gt;
        &lt;/form&gt;
        {loading ? &lt;strong&gt;Loding...&lt;/strong&gt; : null}
      &lt;/div&gt;
      &lt;hr&gt;&lt;/hr&gt;
      &lt;div className={coinChallenge.tablecontainer}&gt;
        &lt;table&gt;
          &lt;thead&gt;
            &lt;tr&gt;
              &lt;th&gt;순위&lt;/th&gt;
              &lt;th&gt;종목&lt;/th&gt;
              &lt;th&gt;기호&lt;/th&gt;
              &lt;th&gt;가격(KRW)&lt;/th&gt;
              &lt;th&gt;총시가&lt;/th&gt;
              &lt;th&gt;거래량(24H)&lt;/th&gt;
              &lt;th&gt;변동(24H)&lt;/th&gt;
              &lt;th&gt;변동(7D)&lt;/th&gt;
            &lt;/tr&gt;
          &lt;/thead&gt;
          &lt;tbody&gt;
            {coins.map((coins) =&gt; (
              &lt;tr key={coins.id}&gt;
                &lt;td className={coinChallenge.rank}&gt;{coins.rank}&lt;/td&gt;
                &lt;td className={coinChallenge.dataColorWhite}&gt;
                  {coins.name.toUpperCase()}
                &lt;/td&gt;
                &lt;td className={coinChallenge.dataColorWhite}&gt;{coins.symbol}&lt;/td&gt;
                &lt;td className={coinChallenge.dataColorWhite}&gt;
                  {parseFloat(
                    coins.quotes.KRW.price.toFixed(3),
                  ).toLocaleString() + &#39;원&#39;}
                &lt;/td&gt;
                &lt;td className={coinChallenge.dataColorWhite}&gt;
                  {parseFloat(
                    coins.quotes.KRW.ath_price.toFixed(3),
                  ).toLocaleString() + &#39;원&#39;}
                &lt;/td&gt;
                &lt;td className={coinChallenge.dataColorWhite}&gt;
                  {parseFloat(
                    coins.quotes.KRW.volume_24h.toFixed(3),
                  ).toLocaleString() + &#39;개&#39;}
                &lt;/td&gt;
                &lt;td
                  className={
                    parseFloat(coins.quotes.KRW.percent_change_24h) &lt; 0
                      ? coinChallenge.dataColorRed
                      : coinChallenge.dataColorBlue
                  }
                &gt;
                  {parseFloat(
                    coins.quotes.KRW.percent_change_24h.toFixed(3),
                  ).toLocaleString()}
                &lt;/td&gt;
                &lt;td
                  className={
                    parseFloat(coins.quotes.KRW.percent_change_7d) &lt; 0
                      ? coinChallenge.dataColorRed
                      : coinChallenge.dataColorBlue
                  }
                &gt;
                  {parseFloat(
                    coins.quotes.KRW.percent_change_7d.toFixed(3),
                  ).toLocaleString()}
                &lt;/td&gt;
              &lt;/tr&gt;
            ))}
          &lt;/tbody&gt;
        &lt;/table&gt;
      &lt;/div&gt;
      &lt;div className={coinChallenge.moreBtndiv}&gt;
        &lt;button className={coinChallenge.moreBtn} onClick={onClick}&gt;
          {loading ? &lt;strong&gt;Loding...&lt;/strong&gt; : &#39;더 보기&#39;}
        &lt;/button&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  )
}

export default CoinTrackerChallengeApp

</code></pre>
<p>CoinChallenge.module.css</p>
<pre><code class="language-css">body {
  background-color: #333;
}

.title {
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0;
  font-family: &#39;Franklin Gothic Medium&#39;, &#39;Arial Narrow&#39;, Arial, sans-serif;
}
.search {
  display: flex;
  justify-content: center;
  align-items: center;
}

.search select {
  width: 70px;
  margin-right: 20px;
}

.tablecontainer {
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}

/* @media (max-width: 330px) {
  .tablecontainer {
    flex-direction: column;
  }
} */

.tablecontainer table {
  border-collapse: collapse;
}

.tablecontainer table thead {
  color: wheat;
  border-bottom: 2px solid brown;
}

.tablecontainer table th {
  padding-bottom: 5px;
}

.tablecontainer table td {
  padding-top: 10px;
}

.moreBtndiv {
  display: flex;
  justify-content: center;
  align-items: center;
}
.moreBtn {
  background-color: transparent; /* 배경색을 투명하게 설정 */
  border: 2px solid brown; /* 테두리 스타일 및 색상 지정 */
  color: white;
  margin-top: 10px;
  padding: 15px;
  min-height: 30px;
  min-width: 600px;
}

.rank {
  color: chocolate;
}

.dataColorWhite {
  color: White;
}

.dataColorRed {
  color: red;
}
.dataColorBlue {
  color: green;
}</code></pre>
<ul>
<li>MovieApp.js<pre><code class="language-js">import { BrowserRouter as Router, Routes, Route } from &#39;react-router-dom&#39;
import MovieHome from &#39;../src/routes/MovieHome&#39;
import Detail from &#39;./routes/Detail&#39;
</code></pre>
</li>
</ul>
<p>// react-router사용할 건데 터미널에 npm install react-router-dom을 입력한다.
// movieApp.js는 더이상 영화를 보여주지 않고 router를 render한다.
// 즉 이곳은 url을 바라보면서 해당 url주소에 따라서 MovieHome, Details 보여줄것이다.
function MovieApp() {
  //react-router-dom 5버전 -&gt; 버전6 바뀐 부분
  // 1. Switch컴포넌트가 Routes컴포넌트로 대체되었습니다.
  // Switch -&gt; Routes
  // 2. Route컴포넌트 사이에 자식 컴포넌트를 넣지 않고, element prop에 자식 컴포넌트를 할당하도록 바뀌었습니다.
  // <Routes>가 하는 일은 Route를 찾는데 Route는 url이다.
  // HashRouter는 주소 앞에 #를 붙여서 사용한다. 대부분 BrowserRouter를 사용하기 때문에 참고만 하자.</p>
<p>  // Movie 컴포넌트에서 타이틀을 클릭해서 movie페이지로 이동할때 a herf=&#39;&#39; 로 이동하게 되면 우리 어플리케이션에 있는 모든 페이지가 리프레시 된다.
  // 딱 movie페이지만 렌더링, 리렌더링 되기를 원하는데, 이때 Link를 사용한다.  다시 Movie.js에서 보기</p>
<p>  //path=&quot;/movie/:id&quot; :id라고 입력해야 페이지넘기면서 데이터를 전달할 수 있다.
  // 다시한번  path=&quot;/movie/:id&quot; 경로 사이에는 항상 &quot;/&quot;이거 붙여야 한다.
  // :variable 즉 :뒤에가 변수이다.
  return (
    <Router>
      <Routes>
        &lt;Route path=&quot;/movie/:id&quot; element={<Detail />}&gt;</Route>
        &lt;Route path=&quot;/&quot; element={<MovieHome />}&gt;</Route>
      </Routes>
    </Router>
  )
}</p>
<p>export default MovieApp</p>
<pre><code>
- component/Movie.js
```js
import PropTypes from &#39;prop-types&#39;
import { Link } from &#39;react-router-dom&#39;
import &#39;../MovieIntro.css&#39; // 추가된 CSS 파일
// react-router사용할 건데 터미널에 npm install react-router-dom을 입력한다.
// Movie 컴포넌트에서 타이틀을 클릭해서 movie페이지로 이동할때 a herf=&#39;&#39; 로 이동하게 되면 우리 어플리케이션에 있는 모든 페이지가 리프레시 된다.
// 딱 movie페이지만 렌더링, 리렌더링 되기를 원하는데, 이때 Link를 사용한다.
// MovieHome에서 id받아서 props에 넘겨주고 여기서 id값을 받아서 Link to로 연동한다.

// 여기서 &lt;Link to={`/movie/${id}`}&gt;{title}&lt;/Link&gt; 작성을 해야,
// 부모 컴포넌트의 path=&quot;/movie:id&quot; :id라고 입력한 부분이 페이지넘기면서 데이터를 전달할 수 있다.
function Movie({ id, medium_cover_image, title, summary, genres }) {
  // return (
  //   &lt;div&gt;
  //     &lt;img src={medium_cover_image} alt={title}&gt;&lt;/img&gt;
  //     &lt;h2&gt;
  //       &lt;Link to={`/movie/${id}`}&gt;{title}&lt;/Link&gt;
  //     &lt;/h2&gt;
  //     &lt;p&gt;{summary.slice(0, 300)}...&lt;/p&gt;
  //     &lt;ul&gt;
  //       {genres.map((g) =&gt; (
  //         &lt;li key={g}&gt;{g}&lt;/li&gt;
  //       ))}
  //     &lt;/ul&gt;
  //   &lt;/div&gt;
  // )
  return (
    &lt;div className=&quot;movie-intro&quot;&gt;
      &lt;img className=&quot;movie-intro-image&quot; src={medium_cover_image} alt={title} /&gt;
      &lt;h2 className=&quot;movie-intro-title&quot;&gt;
        &lt;Link to={`/movie/${id}`}&gt;{title}&lt;/Link&gt;
      &lt;/h2&gt;
      &lt;p className=&quot;movie-intro-summary&quot;&gt;{summary.slice(0, 300)}...&lt;/p&gt;
      &lt;ul className=&quot;movie-intro-genres&quot;&gt;
        {genres.map((g) =&gt; (
          &lt;li key={g}&gt;{g}&lt;/li&gt;
        ))}
      &lt;/ul&gt;
    &lt;/div&gt;
  )
}
// propTypes 선언하는것 잘보자
// 항상 소문자
Movie.propTypes = {
  id: PropTypes.number.isRequired,
  medium_cover_image: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string).isRequired,
}

export default Movie
</code></pre><ul>
<li>routes/MovieHome.js<pre><code class="language-js">import { useEffect, useState } from &#39;react&#39;
import Movie from &#39;../components/Movie&#39;
import &#39;../MovieHome.css&#39; // 추가된 CSS 파일
</code></pre>
</li>
</ul>
<p>// react-router사용할 건데 터미널에 npm install react-router-dom을 입력한다.
function MovieHome() {
  const [loading, setLoading] = useState(true)
  const [movies, setMovies] = useState([])</p>
<p>  // async, await를 사용하자
  // <a href="https://yts.mx/api/v2/list_movies.json?minimum_rating=9&amp;sort_by=year">https://yts.mx/api/v2/list_movies.json?minimum_rating=9&amp;sort_by=year</a>
  const getMovies = async () =&gt; {
    const response = await fetch(
      //<code>https://yts.mx/api/v2/list_movies.json?minimum_rating=8.5&amp;sort_by=rating&amp;limit=20</code>,
      <code>https://yts.mx/api/v2/list_movies.json?sort_by=year&amp;limit=21&amp;page=2</code>,
    )
    const json = await response.json()
    setMovies((current) =&gt; json.data.movies)
    setLoading((current) =&gt; false)
  }</p>
<p>  useEffect(() =&gt; {
    getMovies()
  }, [])</p>
<p>  console.log(movies)</p>
<p>  return (
    <div>
      <h1>MovieApp</h1>
      <hr></hr>
      {loading ? (
        <h1>Loding...</h1>
      ) : (
        <div className="container">
          {movies.map((movie) =&gt; (
            <Movie
              key={movie.id}
              id={movie.id}
              medium_cover_image={movie.medium_cover_image}
              title={movie.title}
              summary={movie.summary}
              genres={movie.genres}
            />
          ))}
        </div>
      )}
    </div>
  )
}</p>
<p>export default MovieHome</p>
<pre><code>- component/Detail.js(미완성)
```js
// MovieHome에서 &lt;Link to={`/movie/${id}`}&gt;{title}&lt;/Link&gt; 작성을 했을때
// 부모 컴포넌트의 path=&quot;/movie:id&quot; :id라고 입력한 부분이 Detail페이지넘기면서 데이터를 넘겨주는데
// Detailpage에서 어떻게 id부분만 받을 수 있나?
// 아래와 같이 useParams를 사용하자.

import { useEffect } from &#39;react&#39;
import { useParams } from &#39;react-router-dom&#39;

function Detail() {
  //  path=&quot;/movie/:id&quot; 경로 사이에는 항상 &quot;/&quot;이거 붙여야 한다.
  // :variable 즉 :뒤에가 변수이다.
  //   const id = useParams()
  //   console.log(id.id)

  //이 형식의 코드는 현재 라우트의 URL 매개변수를 가져오는 데 사용된다.
  // URL이 &quot;/movies/53528&quot;일 때, useParams를 사용하여 id 값을 추출할 때 아래와 같은 형식의 코드로 가져올수있다.
  const { id } = useParams()
  console.log(id)
  // https://yts.mx/api/v2/movie_details.json?movie_id=

  const getMovieDetail = async () =&gt; {
    const response = await fetch(
      `https://yts.mx/api/v2/movie_details.json?movie_id=${id}`,
    )
    const json = response.json()

    console.log(json)
  }

  useEffect(() =&gt; {
    getMovieDetail()
  }, [])
  return &lt;h1&gt;Detail&lt;/h1&gt;
}

export default Detail
</code></pre><br>


<h2 id="retrospection">Retrospection</h2>
<ul>
<li><p>코드트래커 첼린지에서 많이 아쉬웠다.</p>
</li>
<li><p>전체적인 디자인이나 셀렉트 태그로 원,달러,엔,위안화를 선택해서 사용자가 총 몇개를 가질수 있는지 표현 하고 싶었으나 잘 안되었다.</p>
</li>
<li><p>Naver 쇼핑 API를 사용해서 최저가를 표현하는 나만의 프로젝트를 실행했으나 알고 봤더니 클라이언트 자체에서는 네이버API의 내용을 가져올수가 없다(하루 허비함 아...........) </p>
</li>
<li><p>그래서 스프링부트와 연동해서 실행해보니 어느정도 성과가 있었다.
(코인앱첼린지와 마찬가지로 부족한 면이 많았다.)</p>
</li>
<li><p>컴포넌트와 라우트를 사용해서 전반적인 리액트 앱이 어떻게 구동되는지 큰틀을 알게되었다.</p>
</li>
<li><p>리액트 돔을 설치하는등 생각보다 리엑트에 좋은 라이브러리가 많았다.</p>
<ul>
<li>import { BrowserRouter as Router, Routes, Route } from &#39;react-router-dom&#39;</li>
<li>import { Link } from &#39;react-router-dom&#39;</li>
</ul>
</li>
<li><p>디자인이 중요하다! 자유자재로 만들수 있어야 한다.</p>
</li>
<li><p>css또한 엄청 중요하다는 것을 알게 되었다.</p>
</li>
<li><p>최종본 : <a href="https://github.com/pmjn1025/react_study">https://github.com/pmjn1025/react_study</a></p>
</li>
</ul>
<hr>
<br>

<h2 id="tommorrow-do-list">Tommorrow do list</h2>
<ul>
<li>포트폴리오 템플릿 공부하기</li>
</ul>
<hr>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[2023.09.09(React JS필기 정리)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.09.09React-JS%ED%95%84%EA%B8%B0-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@sago_mungcci/2023.09.09React-JS%ED%95%84%EA%B8%B0-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sat, 09 Sep 2023 07:09:31 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/18b91836-ed65-4536-86d7-2d4d9455ce74/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<p>⦁reactApp설치
<a href="https://velog.io/@sago_mungcci/2023.09.09React-App-%EC%84%A4%EC%B9%98">https://velog.io/@sago_mungcci/2023.09.09React-App-%EC%84%A4%EC%B9%98</a></p>
<hr>
<br>

<h2 id="til">TIL</h2>
<ul>
<li><p>리액트 앱을 설치해서 본격적인 리액트 다루는 법을 배우기 시작함.</p>
</li>
<li><p>index.js</p>
<pre><code class="language-js">import React from &#39;react&#39;
import ReactDOM from &#39;react-dom/client&#39;
//import App from &#39;./App&#39;
//import AppEffect from &#39;./AppEffect&#39;
//import AppDeps from &#39;./AppDeps&#39;
import AppCleanUp from &#39;./AppCleanUp&#39;
//import &#39;./styles.css&#39;
</code></pre>
</li>
</ul>
<p>const root = ReactDOM.createRoot(document.getElementById(&#39;root&#39;))
//root.render(&lt;React.StrictMode&gt;{/* <App /> */ <AppEffect />}&lt;/React.StrictMode&gt;)
//root.render(<AppEffect />)
//root.render(<AppDeps />)
root.render(<AppCleanUp />)</p>
<pre><code>
- app.js
```js
import Button from &#39;./Button&#39;

// npm i prop-types 설치하기
function App() {
  return (
    &lt;div&gt;
      &lt;h1&gt;Welcome Back!&lt;/h1&gt;
      &lt;Button text={&#39;continue&#39;}&gt;&lt;/Button&gt;
    &lt;/div&gt;
  )
}

export default App
</code></pre><ul>
<li>button.js<pre><code class="language-js">import PropTypes from &#39;prop-types&#39;
import styles from &#39;./Button.module.css&#39;
import title from &#39;./title.module.css&#39;
</code></pre>
</li>
</ul>
<p>function Button({ text }) {
  return (
    // 이렇게 할 필요 없이 위에 임포트 하면 된다.
    // &lt;button style={{ backgroundColor: &#39;tomato&#39;, color: &#39;white&#39; }}&gt;
    //   {text}
    // </button>
    <div>
      <h1 className={title.title}>Welcome Back!</h1>
      <button className={styles.btn}>{text}</button>
    </div>
  )
}</p>
<p>Button.propTypes = {
  text: PropTypes.string.isRequired,
}</p>
<p>export default Button</p>
<pre><code>
- AppEffect.js
```js
import { useState, useEffect } from &#39;react&#39;

// npm i prop-types 설치하기
function AppEffect() {
  const [counter, setValue] = useState(0)
  const onClick = () =&gt; {
    setValue((prev) =&gt; prev + 1)
  }

  // rendering이 두번되는 현상이 있어서 찾아보았더니 index.js에
  // React.StrictMode 테그에 감싸져 있어서 그렇다고 합니다.
  // StrictMode는 create-react-app로 설치했을 때 기본적으로 생성되는 테그로,
  // 해당 테그로 감싸져 있는 경우 자손까지 검사한다해서 두 번 실행된다고 합니다.
  // React.StrictMode 테그를 지우시고 해보세요.
  // 오류 : Error handling response: TypeError: Cannot read properties of undefined (reading &#39;always&#39;)
  // ==&gt; 드래그프리때문

  // 1. 지금 아래와 같이 처음에 api를 호출하고 또 state가 변경될 때 또 호출하게 된다.
  // 처음 들어왔을때 한번만 실행 시키고 state값이 변경되도 호출하지 않게하고 싶다.
  console.log(&#39;i run all the time&#39;)
  //   const iRunOnlyOnce = () =&gt; {
  //     console.log(&#39;i run only once&#39;)
  //   }
  // React.useEffect() --&gt; 첫번째 매개변수는 처음 한번만 실행시키고 싶은 코드, 두번째는 deps 추후 설명
  //useEffect(iRunOnlyOnce, [])
  useEffect(() =&gt; {
    console.log(&#39;i run only once&#39;)
  }, [])
  return (
    &lt;div&gt;
      &lt;h1&gt;AppEffect{counter}&lt;/h1&gt;
      &lt;button onClick={onClick}&gt;Click me!&lt;/button&gt;
    &lt;/div&gt;
  )
}

export default AppEffect
</code></pre><ul>
<li>deps.js<pre><code class="language-js">import { useState, useEffect } from &#39;react&#39;
</code></pre>
</li>
</ul>
<p>// npm i prop-types 설치하기
function AppDeps() {
  const [counter, setValue] = useState(0)
  const [keyword, setKeyword] = useState(&#39;&#39;)
  const onClick = () =&gt; {
    setValue((prev) =&gt; prev + 1)
  }
  const onChange = (event) =&gt; {
    setKeyword(event.target.value)
  }</p>
<p>  // 일반문장
  //console.log(&#39;i run all the time&#39;)</p>
<p>  // 일반문장에 useEffect를 씌웠다고 생각!
  useEffect(() =&gt; {
    console.log(&#39;i run only once&#39;)
  }, [])</p>
<p>  // 서칭시 (onChange)에도 아래 return부분이 리렌더링 되면서 함수를 실행시키고
  // 클릭할때도 마찬가지로 return부분이 리렌더링 되면서 함수를 실행시킨다.
  // 불필요 한 작동을 계속하고 있다.
  // 따라서 서칭시에는 onChange이벤트만 실행시키고
  // 클릭시에는 onClick이벤트만 실행시키고 싶다.
  //console.log(&#39;Search for&#39;, keyword)</p>
<p>  // deps : 저 배열문안에 있는 변수가 변할때만 실행시킨다.(keyword는 검색문)
  // 지금 여기서는 if문을 주어서 변수의 값이 변할 때 조건에 따라서 실행시킨다.
  useEffect(() =&gt; {
    // if (keyword !== &#39;&#39; &amp;&amp; keyword.length &gt; 5) {
    //   console.log(&#39;Search for&#39;, keyword)
    // }
    console.log(&#39;i run when keyword change&#39;, keyword)
  }, [keyword])</p>
<p>  useEffect(() =&gt; {
    console.log(&#39;i run when counter change&#39;, counter)
  }, [counter])</p>
<p>  // keyword나 counter 둘중에 하나의 값만 바뀌어도 실행됨
  useEffect(() =&gt; {
    console.log(&#39;i run when keyword&amp;counter change&#39;, counter)
  }, [keyword, counter])</p>
<p>  return (
    <div>
      <h1>AppEffect</h1>
      <input
        type="text"
        placeholder="Seacrch Here"
        onChange={onChange}
        value={keyword}
      ></input>
      <h3>{counter}</h3>
      <button onClick={onClick}>Click me!</button>
    </div>
  )
}</p>
<p>export default AppDeps</p>
<pre><code>
- AppCleanUp.js
```js
import { useState, useEffect } from &#39;react&#39;

// showing이 참일때
// im here이 hello() 컴포넌트에서 실행되고 콘솔에 찍히고 있다.
// showing이 거짓일때
// im here이 hello() 컴포넌트에서 destroy되면서 없어진다.(삭제된다.)
// ** 참고
// useEffect(() =&gt; something(), [변수A]) 라고하면, 변수A가 변경될 떄 마다 useEffect는 실행된다. 변수A가 변경되면,
// 이전의 변수A 값을 가지고 return 함수가 실행된다.
// ex) 변수A =1 -&gt;2 변경되는 시점에서 , useEffect()에서 return 외에는 변수A는 2이고, return 상황에서는 변수A는 1이다.
// 뒤에 [ dependency ]에 아무것도 없다면( ex) [] ) 첫 렌더링시에 실행되고, return은 컴포넌트 unmount시(영상의 destroy시) 실행된다.
// 부모 컴포넌트 위에 자식컴포넌트가 있듯이 AppCleanUp 컴포넌트위에 Hello 컴포넌트가 쌓였고 이 쌓인 컴포넌트가 destroy될대 return값을 반환한다.
function Hello() {
  //   function byeFn() {
  //     console.log(&#39;bye&#39;)
  //   }

  //   function hiFn() {
  //     console.log(&#39;hi&#39;)
  //     return byeFn
  //   }
  //   useEffect(hiFn, [])
  // 위 주석친 3문장이 아래의 useEffect와 같다
  useEffect(() =&gt; {
    console.log(&#39;im here&#39;)
    return () =&gt; console.log(&#39;im destroy&#39;) //destroy되면서 실행되는 구문
  }, [])
  return &lt;h1&gt;Hello&lt;/h1&gt;
}

// npm i prop-types 설치하기
function AppCleanUp() {
  const [showing, setShowing] = useState(false)
  const onClick = () =&gt; {
    setShowing((prev) =&gt; !prev)
  }
  return (
    &lt;div&gt;
      {showing ? &lt;Hello /&gt; : null}
      &lt;button onClick={onClick}&gt;{showing ? &#39;Hide&#39; : &#39;Show&#39;}&lt;/button&gt;
    &lt;/div&gt;
  )
}

export default AppCleanUp
</code></pre><hr>
<br>


<h2 id="retrospection">Retrospection</h2>
<ul>
<li>컴포넌트들을 쌓아서 개발한다는 느낌을 받았다.</li>
<li>AppCleanUp.js에서<pre><code class="language-js">useEffect(() =&gt; {
  console.log(&#39;im here&#39;)
  return () =&gt; console.log(&#39;im destroy&#39;) //destroy되면서 실행되는 구문
}, [])
return &lt;h1&gt;Hello&lt;/h1&gt;</code></pre>
<pre><code class="language-js">return () =&gt; console.log(&#39;im destroy&#39;) //destroy되면서 실행</code></pre>
이부분이 이해가 잘안갔는데,</li>
</ul>
<p>자바에서는 일반적으로 메서드가 호출되어 실행될때 return문까지 실행되기때문에 굉장히 헷갈렸다.</p>
<p>정확히 이해하려면 2가지를 이해해야 하는데, useEffect()이고 하나는 component인것 같다.</p>
<p>컴포넌트가 부모 컴포넌트위에 자식 컴포넌트가 쌓이면 그 자식 컴포넌트 내부에 있는 함수가 실행된다.</p>
<p>실행하면서 useEffect()에서는 특이한점이 있는데,</p>
<p>useEffect()내부에 있는 코드를 한번만 실행되는 동시에 return문에 있는 함수는 반환을 하지 않는다. 그러나 해당 &quot;컴포넌트&quot;가 destroy함과 동시에 useEffect에있는 return문을 반환하는 것이다.</p>
<p>컴포넌트도 함수로 작동되기 때문에 굉장히 헷갈렸다.</p>
<hr>
<br>

<h2 id="tommorrow-do-list">Tommorrow do list</h2>
<ul>
<li>휴식이다~!</li>
</ul>
<hr>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[2023.09.09(React App 설치)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.09.09React-App-%EC%84%A4%EC%B9%98</link>
            <guid>https://velog.io/@sago_mungcci/2023.09.09React-App-%EC%84%A4%EC%B9%98</guid>
            <pubDate>Sat, 09 Sep 2023 06:54:05 GMT</pubDate>
            <description><![CDATA[<h2 id="today-do-list">Today do list</h2>
<p>⦁ reactApp설치하는 법
 -node.js 설치한다 (<a href="https://nodejs.org/ko/download/">https://nodejs.org/ko/download/</a>)</p>
<p> -vscode의 터미널에 해당 폴더 경로에 react install 해주어야 함.
 (<a href="https://devbirdfeet.tistory.com/3">https://devbirdfeet.tistory.com/3</a>)
 npm install -g create-react-app 이걸로 설치함</p>
<p> 터미널에 npm install -g create-react-app 이거 입력함</p>
<pre><code> PS C:\Users\sagoMungcci\Desktop\react-project&gt; npm install -g create-react-app
npm WARN deprecated tar@2.2.2: This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.
added 67 packages in 3s
5 packages are looking for funding
  run `npm fund` for details
</code></pre><p>그후 npx create-react-app react-app(폴더명)
입력하면 폴더에 해당 react 패키지가 생성됨</p>
<pre><code>PS C:\Users\sagoMungcci\Desktop\react-project&gt; npx create-react-app react-app

Creating a new React app in C:\Users\sagoMungcci\Desktop\react-project\react-app.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...


added 1439 packages in 1m

241 packages are looking for funding
  run `npm fund` for details
Git repo not initialized Error: Command failed: git --version
    at checkExecSyncError (node:child_process:885:11)
    at execSync (node:child_process:957:15)
    at tryGitInit (C:\Users\sagoMungcci\Desktop\react-project\react-app\node_modules\react-scripts\scripts\init.js:46:5)
    at module.exports (C:\Users\sagoMungcci\Desktop\react-project\react-app\node_modules\react-scripts\scripts\init.js:276:7)
    at [eval]:3:14
    at Script.runInThisContext (node:vm:123:12)
    at Object.runInThisContext (node:vm:299:38)
    at node:internal/process/execution:79:19
    at [eval]-wrapper:6:22 {
  status: 1,
  signal: null,
  output: [ null, null, null ],
  pid: 11228,
  stdout: null,
  stderr: null
}

Installing template dependencies using npm...

added 69 packages, and changed 1 package in 7s

245 packages are looking for funding
  run `npm fund` for details
Removing template package using npm...


removed 1 package, and audited 1508 packages in 3s

245 packages are looking for funding
  run `npm fund` for details

6 high severity vulnerabilities

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

Success! Created react-app at C:\Users\함주형\Desktop\react-project\react-app
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd react-app
  npm start

Happy hacking!
</code></pre><hr>
<blockquote>
<ul>
<li>중요!</li>
</ul>
</blockquote>
<ul>
<li>터미널에서 npm run start 할때 react 패키지가 있는 폴더의 경로에 가서 npm run start 해야한다.</li>
<li>상위폴더 이동 명령어는 cd..이고</li>
<li>해당 폴더 경로 이동은 cd 폴더명이다.</li>
</ul>
<ul>
<li>ps 이거 찾는데 하루종일 걸렸다. 뭐가 문제인지 몰라서 아.......
문제의 시작은 npm run start가 안되서 뭐가 문제인지 모름.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[2023.09.07(React JS필기 정리)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.09.07React-JS%ED%95%84%EA%B8%B0-%EC%A0%95%EB%A6%AC-ji9enlnk</link>
            <guid>https://velog.io/@sago_mungcci/2023.09.07React-JS%ED%95%84%EA%B8%B0-%EC%A0%95%EB%A6%AC-ji9enlnk</guid>
            <pubDate>Thu, 07 Sep 2023 07:44:03 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/7654e2fd-ec65-4500-859c-fac644f8b0f5/image.png" alt=""></p>
<h2 id="today-do-list">Today do list</h2>
<ul>
<li>Nomad Coder - ReactJS로 영화 웹 서비스 만들기
⦁ props에 대해서 배움</li>
</ul>
<hr>
<br>

<h2 id="til">TIL</h2>
<ul>
<li><p>props1.html</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot; /&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
  &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;!-- react import --&gt;
&lt;!-- &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.development.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;
&lt;!-- babel import(jsx -&gt;react로 변환) --&gt;
&lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
&lt;!-- 바벨 사용시 type 입력해주어야 한다. --&gt;
&lt;script type=&quot;text/babel&quot;&gt;
  // 분할과 정복(divide&amp;Conquer(분할정복))
  // App이 부모 컴포넌트 이고 MinutesToHours, KmToMiles가 자식 컴포넌트이다
  // 이제부터 우리가 할것은 부모 컴포넌트로 부터 자식컴포넌트로 데이터를 보낼것이다.

  // 상황 가정 : 우리가 만들려는 app에 다양한 기능들이 있는 버튼들이 있다.(로그인, 프로필, 화면이동 등등)
  // 그런데 보면 각 버튼들의 디자인이 동일한 것을 알수있다. --&gt; 디자이너들이 디자인을 만들기 때문
  // 이렇게 동일한 디자인의 버튼에 대해서 우리가 알고 싶은 것은 어떻게 리액트 컴포넌트를 재활용 할 수 있는 지를 알고싶은것

  // component라고 하는 것은 JSX를 반환하는 함수 일뿐이다.
  // component는 항상 첫글자 대문자로
  // SaveBtn(), ConfrimBtn() ==&gt; 함수형 컴포넌트
  // 이렇게 되면 버튼마다 일일이 스타일 지정해주어야 한다.
  // props1에서 계속
  function SaveBtn() {
    return (
      &lt;button
        style={{
          backgroundColor: &#39;brown&#39;,
          color: &#39;White&#39;,
          padding: &#39;10px 20px&#39;,
          border: 0,
          borderRadius: 10,
        }}
      &gt;
        Save Changes
      &lt;/button&gt;
    )
  }
  function ConfrimBtn() {
    return (
      &lt;button
        style={{
          backgroundColor: &#39;brown&#39;,
          color: &#39;White&#39;,
          padding: &#39;10px 20px&#39;,
          border: 0,
          borderRadius: 10,
        }}
      &gt;
        Confrim
      &lt;/button&gt;
    )
  }

  function App() {
    // component는 항상 첫글자 대문자로
    return (
      &lt;div&gt;
        &lt;h1&gt;Your Profile&lt;/h1&gt;
        &lt;SaveBtn /&gt;
        &lt;span&gt; &lt;/span&gt;
        &lt;ConfrimBtn /&gt;
      &lt;/div&gt;
    )
  }
  const root = document.querySelector(&#39;#root&#39;)
  ReactDOM.render(&lt;App /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
&lt;/script&gt;
&lt;/html&gt;

</code></pre>
</li>
</ul>
<pre><code>
- props2
```html
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
  &lt;!-- react import --&gt;
  &lt;!-- &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt; --&gt;
  &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.development.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;
  &lt;!-- babel import(jsx -&gt;react로 변환) --&gt;
  &lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
  &lt;!-- 바벨 사용시 type 입력해주어야 한다. --&gt;
  &lt;script type=&quot;text/babel&quot;&gt;
    // props.html에서 계속
    // 따라서 버튼 컴포넌트를 만들어서 재활용할 수있다.
    // 하나의 컴포넌트(객체와 비슷)에서 자식 컴포넌트 props에 따라서 다르게 출력하면 어떨까?
    // 부모 컴포넌트에서 정의한 자식 컴포넌트의 props를 받기위해서는 아래와 같이 할수있다.
    // props는 하나의 인자만 있다.

    /*function Btn(props) {
       console.log(props)
       return (
         &lt;button
           style={{
             backgroundColor: &#39;brown&#39;,
             color: &#39;White&#39;,
             padding: &#39;10px 20px&#39;,
             border: 0,
             borderRadius: 10,
           }}
         &gt;
           {props.text}
         &lt;/button&gt;
       )
     }
    */

    // 위 방식 말고 바로 props.text를 받는 방법은 아래와 같다
    // {text}를 넣어주면 props.text와 같다.
    function Btn({ text, big, bName }) {
      console.log({ text, big, bName })

      const handleClick = (event) =&gt; {
        BtnClick(event, bName)
      }

      return (
        &lt;button
          style={{
            backgroundColor: &#39;brown&#39;,
            color: &#39;White&#39;,
            padding: &#39;10px 20px&#39;,
            border: 0,
            borderRadius: 10,
            fontSize: big ? 18 : 10,
          }}
          onClick={handleClick}
        &gt;
          {text}
        &lt;/button&gt;
      )
    }

    function BtnClick(event, bName) {
      console.log(event)
      console.log(bName)

      if (bName === &#39;sChange&#39;) {
        return alert(&#39;변경완료되었습니다.&#39;)
      }

      if (bName === &#39;sConfirm&#39;) {
        alert(&#39;확인되었습니다.&#39;)
      }
    }
    function App() {
      // component는 항상 첫글자 대문자로
      // 부모컴포넌트에 있는 자식 컴포넌트의 properties를 자식 컴포넌트(함수)에 보내서 다르게 출력이 가능하다.
      // 자식 props에 있는 것(html의 tag의 type과 같은거)은 마음대로 정의가능하다.(나는 text로 정의한것일 뿐이다.)
      return (
        &lt;div&gt;
          &lt;h1&gt;Your Profile&lt;/h1&gt;
          &lt;Btn text=&quot;Save Changes&quot; bName=&quot;sChange&quot; big={true} /&gt;
          &lt;span&gt; &lt;/span&gt;
          &lt;Btn text=&quot;Confirm&quot; bName=&quot;sConfirm&quot; big={false} /&gt;
        &lt;/div&gt;
      )
    }
    const root = document.querySelector(&#39;#root&#39;)
    ReactDOM.render(&lt;App /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
  &lt;/script&gt;
&lt;/html&gt;
</code></pre><ul>
<li>props1practice.html<pre><code class="language-html"></code></pre>
</li>
</ul>
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
  <!-- react import -->
  <!-- <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> -->
  <script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
  <!-- babel import(jsx ->react로 변환) -->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <!-- 바벨 사용시 type 입력해주어야 한다. -->
  <script type="text/babel">
    // props.html에서 계속
    // 따라서 버튼 컴포넌트를 만들어서 재활용할 수있다.
    // 하나의 컴포넌트(객체와 비슷)에서 자식 컴포넌트 props에 따라서 다르게 출력하면 어떨까?
    // 부모 컴포넌트에서 정의한 자식 컴포넌트의 props를 받기위해서는 아래와 같이 할수있다.
    // props는 하나의 인자만 있다.

<pre><code>/*function Btn(props) {
   console.log(props)
   return (
     &lt;button
       style={{
         backgroundColor: &#39;brown&#39;,
         color: &#39;White&#39;,
         padding: &#39;10px 20px&#39;,
         border: 0,
         borderRadius: 10,
       }}
     &gt;
       {props.text}
     &lt;/button&gt;
   )
 }
*/

// 위 방식 말고 바로 props.text를 받는 방법은 아래와 같다
// {text}를 넣어주면 props.text와 같다.
function Btn({ text, big, bName, displayHello, setDisplayHello }) {
  console.log({ text, big, bName })

  const handleClick = (event) =&gt; {
    BtnClick(event, bName, displayHello, setDisplayHello)
  }

  return (
    &lt;button
      style={{
        backgroundColor: &#39;brown&#39;,
        color: &#39;White&#39;,
        padding: &#39;10px 20px&#39;,
        border: 0,
        borderRadius: 10,
        fontSize: big ? 18 : 10,
      }}
      onClick={handleClick}
    &gt;
      {text}
    &lt;/button&gt;
  )
}

function BtnClick(event, bName, displayHello, setDisplayHello) {
  console.log(event)
  console.log(bName)

  if (bName === &#39;sChange&#39;) {
    return alert(&#39;변경완료되었습니다.&#39;)
    setDisplayHello(false)
    console.log(displayHello)
  }

  if (bName === &#39;sConfirm&#39;) {
    alert(&#39;확인되었습니다.&#39;)
    setDisplayHello(true)
    console.log(displayHello)
  }
}
function App() {
  const [displayHello, setDisplayHello] = React.useState(false)

  // component는 항상 첫글자 대문자로
  // 부모컴포넌트에 있는 자식 컴포넌트의 properties를 자식 컴포넌트(함수)에 보내서 다르게 출력이 가능하다.
  // 자식 props에 있는 것(html의 tag의 type과 같은거)은 마음대로 정의가능하다.(나는 text로 정의한것일 뿐이다.)
  return (
    &lt;div&gt;
      &lt;h1&gt;Your Profile&lt;/h1&gt;
      &lt;Btn
        text=&quot;Save Changes&quot;
        bName=&quot;sChange&quot;
        big={true}
        displayHello={displayHello}
        setDisplayHello={setDisplayHello}
      /&gt;
      &lt;span&gt; &lt;/span&gt;
      &lt;Btn
        text=&quot;Confirm&quot;
        bName=&quot;sConfirm&quot;
        big={false}
        displayHello={displayHello}
        setDisplayHello={setDisplayHello}
      /&gt;
      {displayHello &amp;&amp; (
        &lt;div&gt;
          &lt;h3&gt;hello&lt;/h3&gt;
        &lt;/div&gt;
      )}
    &lt;/div&gt;
  )
}
const root = document.querySelector(&#39;#root&#39;)
ReactDOM.render(&lt;App /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())</code></pre><p>  </script></p>
</html>

<pre><code>
- props2memo.html

```html
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
  &lt;!-- react import --&gt;
  &lt;!-- &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt; --&gt;
  &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.development.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;
  &lt;!-- babel import(jsx -&gt;react로 변환) --&gt;
  &lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
  &lt;!-- 바벨 사용시 type 입력해주어야 한다. --&gt;
  &lt;script type=&quot;text/babel&quot;&gt;
    // props.html에서 계속
    // 따라서 버튼 컴포넌트를 만들어서 재활용할 수있다.
    // 하나의 컴포넌트(객체와 비슷)에서 자식 컴포넌트 props에 따라서 다르게 출력하면 어떨까?
    // 부모 컴포넌트에서 정의한 자식 컴포넌트의 props를 받기위해서는 아래와 같이 할수있다.
    // props는 하나의 인자만 있다.

    /*function Btn(props) {
           console.log(props)
           return (
             &lt;button
               style={{
                 backgroundColor: &#39;brown&#39;,
                 color: &#39;White&#39;,
                 padding: &#39;10px 20px&#39;,
                 border: 0,
                 borderRadius: 10,
               }}
             &gt;
               {props.text}
             &lt;/button&gt;
           )
         }
        */

    // 위 방식 말고 바로 props.text를 받는 방법은 아래와 같다
    // {text}를 넣어주면 props.text와 같다.
    // onClick은 changeValue()함수이다.
    function Btn({ text, onClick }) {
      console.log(text, &#39; was render &#39;)
      // 여기서 onClick={Method}가 이벤트 리스너이다.
      return (
        &lt;button
          onClick={onClick}
          style={{
            backgroundColor: &#39;brown&#39;,
            color: &#39;White&#39;,
            padding: &#39;10px 20px&#39;,
            border: 0,
            borderRadius: 10,
          }}
        &gt;
          {text}
        &lt;/button&gt;
      )
    }

    // 부모 컴포넌트의 state를 변경하면 당연히 그 자식 컴포넌트들도 Re-render가 일어남.
    // 불필요한 렌더링이 발생할 수도 있는데, 이 경우에는 React.memo()로 prop의 변경이 일어난 부분만 렌더링 시킬 수 있음.
    // 아주 많은 자식 컴포넌트를 가지고 있는 부모 컴포넌트일 때 사용하면 될 듯.
    const MemorizedBtn = React.memo(Btn)
    function App() {
      // 이번강의에서 &lt;Btn&gt;에 onClick 함수를 추가할것이다.
      const [value, setValue] = React.useState(&#39;Save Changes&#39;)
      const changeValue = () =&gt; setValue((currnet) =&gt; &#39;Revert Changes&#39;)
      // 중요 ** 여기서 onClick={changeValue}은 이벤트 리스너가 아니라 props이다!
      // React.useState(초기값) 에서 setVariable과 관련된 전체가 다시 렌더링된다.
      // 즉, 부모 컴포넌트가 어떤 state값이 변경이 되면 모든 자식 컴포넌트는 다시 그려질 것
      //--&gt; react.Memo()를 사용해서 변경된 것만 리렌더링 할수있다.
      return (
        &lt;div&gt;
          &lt;h1&gt;Your Profile&lt;/h1&gt;
          &lt;MemorizedBtn text={value} onClick={changeValue} /&gt;
          &lt;span&gt; &lt;/span&gt;
          &lt;MemorizedBtn text=&quot;Confirm&quot; /&gt;
        &lt;/div&gt;
      )
    }
    const root = document.querySelector(&#39;#root&#39;)
    ReactDOM.render(&lt;App /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
  &lt;/script&gt;
&lt;/html&gt;

</code></pre><ul>
<li>propstype.html</li>
</ul>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
  &lt;!-- react import --&gt;
  &lt;!-- &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt; --&gt;
  &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.development.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;
  &lt;!-- prop-type import --&gt;
  &lt;!--https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js을 임포트해야한다.  --&gt;
  &lt;script src=&quot;https://unpkg.com/prop-types@15.7.2/prop-types.js&quot;&gt;&lt;/script&gt;
  &lt;!-- babel import(jsx -&gt;react로 변환) --&gt;
  &lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
  &lt;!-- 바벨 사용시 type 입력해주어야 한다. --&gt;
  &lt;script type=&quot;text/babel&quot;&gt;
    // props.html에서 계속
    // 따라서 버튼 컴포넌트를 만들어서 재활용할 수있다.
    // 하나의 컴포넌트(객체와 비슷)에서 자식 컴포넌트 props에 따라서 다르게 출력하면 어떨까?
    // 부모 컴포넌트에서 정의한 자식 컴포넌트의 props를 받기위해서는 아래와 같이 할수있다.
    // props는 하나의 인자만 있다.

    /*function Btn(props) {
           console.log(props)
           return (
             &lt;button
               style={{
                 backgroundColor: &#39;brown&#39;,
                 color: &#39;White&#39;,
                 padding: &#39;10px 20px&#39;,
                 border: 0,
                 borderRadius: 10,
               }}
             &gt;
               {props.text}
             &lt;/button&gt;
           )
         }
        */

    // 위 방식 말고 바로 props.text를 받는 방법은 아래와 같다
    // {text}를 넣어주면 props.text와 같다.
    // onClick은 changeValue()함수이다.
    // 두번째 매개변수가 특이한데 fontSize =24를 지정하면 프롭을 지정하지 않은 컴포넌트에 fontSize = 24가 추가된다.
    function Btn({ text, fontSize = 24 }) {
      return (
        &lt;button
          style={{
            backgroundColor: &#39;brown&#39;,
            color: &#39;White&#39;,
            padding: &#39;10px 20px&#39;,
            border: 0,
            borderRadius: 10,
            fontSize: fontSize,
          }}
        &gt;
          {text}
        &lt;/button&gt;
      )
    }

    // react.js에서는 문제없는 코드라고 인식해서 오류가 출력되지 않는 부분을
    // 각 프롭타입을 지정해서 경고문을 볼수 있다. 프롭의 타입을 지정해 놓으면 왜 적용이 안되는지 알수있다.
    Btn.propTypes = {
      text: PropTypes.string.isRequired,
      fontSize: PropTypes.number.isRequired,
    }

    function App() {
      // props를 넘겨줄때 문자는 =&quot;일&quot;, ={&#39;일&#39;} || 숫자는 ={1}이렇게 넘겨줄수 있다.
      return (
        &lt;div&gt;
          &lt;Btn text=&quot;Save Changes&quot; fontSize={18} /&gt;
          &lt;Btn text={&#39;continue&#39;} /&gt;
          &lt;Btn text={14} fontSize={&#39;confirm&#39;} /&gt;
        &lt;/div&gt;
      )
    }
    const root = document.querySelector(&#39;#root&#39;)
    ReactDOM.render(&lt;App /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
  &lt;/script&gt;
&lt;/html&gt;

</code></pre>
<hr>
<br>


<h2 id="retrospection">Retrospection</h2>
<ul>
<li><p>state, component, props 등등 여러가지 용어가 헷갈렸는데, 윤곽이잡히기 시작했고, 또 중요한점은 용어들이 익숙해지지 시작했다.</p>
</li>
<li><p>니코샘이 말씀해 주신것처럼 코드를 이해하고 왜 이렇게 되는거지? 라고 스스로 이해하는 과정이 오래걸린것 같다.</p>
</li>
<li><p>특히 html과 js 그리고 CSS에 대한 공부를 좀더 해야겠다는 생각과 더불어 chatGPT를 활용하는 것도 팁이과 도구라는 것을 깨닫게 되었다.</p>
</li>
<li><p>분할과 정복이라는 개발방식을 이해하고 reactJS 코드를 보니 아 콤포넌트별로 html, JS, Css를 개발할수 있어서 효율적이라는 생각이 들었다.</p>
</li>
<li><p>다시한번 스스로 코드를 보면서 컴퓨터가 이해는 방식을 따라가면서 코드를 이해(디버깅)하는 습관을 가져야 겠다.</p>
</li>
</ul>
<hr>
<br>

<h2 id="tommorrow-do-list">Tommorrow do list</h2>
<ul>
<li>CREATE REACT APP</li>
</ul>
<hr>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[2023.09.07(React JS필기 정리)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.09.07React-JS%ED%95%84%EA%B8%B0-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@sago_mungcci/2023.09.07React-JS%ED%95%84%EA%B8%B0-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Thu, 07 Sep 2023 02:18:16 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/899904f0-674c-41fc-83a3-cc8e62b7312c/image.png" alt=""></p>
<ul>
<li>Nomad Coder - ReactJS로 영화 웹 서비스 만들기</li>
</ul>
<blockquote>
<p>분할과 정복 : <a href="https://velog.io/@sago_mungcci/2023.09.06%EB%B6%84%ED%95%A0%EA%B3%BC-%EC%A0%95%EB%B3%B5">https://velog.io/@sago_mungcci/2023.09.06%EB%B6%84%ED%95%A0%EA%B3%BC-%EC%A0%95%EB%B3%B5</a></p>
</blockquote>
<ul>
<li><p>inputstate1</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot; /&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
  &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;!-- react import --&gt;
&lt;!-- &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.development.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;
&lt;!-- babel import(jsx -&gt;react로 변환) --&gt;
&lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
&lt;!-- 바벨 사용시 type 입력해주어야 한다. --&gt;
&lt;script type=&quot;text/babel&quot;&gt;
  function App() {
    // &lt;label&gt;은 &lt;input&gt;옆에 사용하는 태그이다.
    // HTML에서 &lt;label&gt;태그를 사용할때 &lt;label for=&#39;해당 인풋태그 아이디&#39;&gt;를 사용한다.
    // reactJS(JSX)에서 &lt;h1 className=&quot;&quot;&gt;, &lt;label&gt;태그를 사용할때 &lt;label htmlFor=&#39;해당 인풋태그 아이디&#39;&gt;를 사용한다.

    // 초기값 즉, React.useSate()에서 첫번째 매개변수 값은 비워놓거나, 0, &quot;&quot; 할 수있다.
    //const [minutes, setMinutes] = React.useState() --&gt; A component is changing an uncontrolled input to be controlled
    // ==&gt;  React.useState() 초기값(첫번째 매개변수의 값을 설정안해줬기때문)
    const [minutes, setMinutes] = React.useState(0)
    // 여기서도 event를 사용할수 있다.
    const onChangeMin = (event) =&gt; {
      console.log(event.target.value)
      setMinutes((current) =&gt; event.target.value) // minutes를 업데이트 해준다.
    }

    const reset = (event) =&gt; {
      console.log(event.target.value)
      setMinutes((current) =&gt; 0) // minutes를 업데이트 해준다.
    }

    return (
      &lt;div&gt;
        &lt;div&gt;
          &lt;h1&gt;Super Converter&lt;/h1&gt;
          &lt;label htmlFor=&quot;minutes&quot;&gt;Minutes : &lt;/label&gt;
          &lt;input
            id=&quot;minutes&quot;
            placeholder=&quot;Minutes&quot;
            type=&quot;number&quot;
            value={minutes}
            onChange={onChangeMin}
          /&gt;
        &lt;/div&gt;
        &lt;h4&gt;you want convert {minutes} &lt;/h4&gt;
        &lt;div&gt;
          &lt;label htmlFor=&quot;hours&quot;&gt;Hours : &lt;/label&gt;
          &lt;input
            id=&quot;hours&quot;
            placeholder=&quot;Hours&quot;
            type=&quot;number&quot;
            value={Math.round(minutes / 60)}
            disabled
          /&gt;
        &lt;/div&gt;
        &lt;button onClick={reset}&gt;Reset&lt;/button&gt;
      &lt;/div&gt;
    )
  }
  const root = document.querySelector(&#39;#root&#39;)
  ReactDOM.render(&lt;App /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
&lt;/script&gt;
&lt;/html&gt;

</code></pre>
</li>
</ul>
<pre><code>
- inputstate2

```html
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
  &lt;!-- react import --&gt;
  &lt;!-- &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt; --&gt;
  &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.development.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;
  &lt;!-- babel import(jsx -&gt;react로 변환) --&gt;
  &lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
  &lt;!-- 바벨 사용시 type 입력해주어야 한다. --&gt;
  &lt;script type=&quot;text/babel&quot;&gt;
    function App() {
      const [amount, setAmount] = React.useState(0)
      const [flipped, setFlipped] = React.useState(false)
      // 여기서도 event를 사용할수 있다.
      const onChange = (event) =&gt; {
        console.log(event.target.value)
        setAmount((current) =&gt; event.target.value)
      }

      const reset = () =&gt; {
        setAmount((current) =&gt; 0)
      }

      // 이 메서드는 위의 메서드와 전혀 다른 값이지만 변수명만 같다.
      // 위에 useState잘보기
      const onfilp = () =&gt; {
        reset()
        setFlipped((current) =&gt; !current)
      }

      return (
        &lt;div&gt;
          &lt;div&gt;
            &lt;h1&gt;Super Converter&lt;/h1&gt;
            &lt;label htmlFor=&quot;minutes&quot;&gt;Minutes : &lt;/label&gt;
            &lt;input
              id=&quot;minutes&quot;
              placeholder=&quot;Minutes&quot;
              type=&quot;number&quot;
              value={flipped === true ? amount * 60 : amount}
              onChange={onChange}
              // JSX덕분에 html형식으로 if문 형식을 작동시킬수 있다
              // 뜻 : 만약 flipped가 true이면 disable ={true}이다.
              disabled={flipped === true}
            /&gt;
          &lt;/div&gt;
          &lt;h4&gt;you want convert {amount} &lt;/h4&gt;
          &lt;div&gt;
            &lt;label htmlFor=&quot;hours&quot;&gt;Hours : &lt;/label&gt;
            &lt;input
              id=&quot;hours&quot;
              placeholder=&quot;Hours&quot;
              type=&quot;number&quot;
              // flipped === true filp : 키를 눌렀을때
              // Why? --&gt; React.useState(false)로 초기값을 false로 했으니까
              value={flipped === true ? amount : Math.round(amount / 60)}
              onChange={onChange}
              // JSX덕분에 html형식으로 if문 형식을 작동시킬수 있다
              // 뜻 : 만약 flipped가 false이면 disable ={true}이다.
              disabled={flipped === false}
            /&gt;
          &lt;/div&gt;
          &lt;button onClick={reset}&gt;Reset&lt;/button&gt;
          &lt;span&gt; &lt;/span&gt;
          &lt;button onClick={onfilp}&gt;
            {flipped === true ? &#39;분을 시간으로 변환&#39; : &#39;시간을 분으로 변환&#39;}
          &lt;/button&gt;
        &lt;/div&gt;
      )
    }
    const root = document.querySelector(&#39;#root&#39;)
    ReactDOM.render(&lt;App /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
  &lt;/script&gt;
&lt;/html&gt;
</code></pre><ul>
<li><p>inputstate3</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot; /&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
  &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;!-- react import --&gt;
&lt;!-- &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.development.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;
&lt;!-- babel import(jsx -&gt;react로 변환) --&gt;
&lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
&lt;!-- 바벨 사용시 type 입력해주어야 한다. --&gt;
&lt;script type=&quot;text/babel&quot;&gt;
  // 지금 아래의 3개의 컴포넌트가 있다.
  function MinutesToHours() {
    const [amount, setAmount] = React.useState(0)
    const [flipped, setFlipped] = React.useState(false)
    // 여기서도 event를 사용할수 있다.
    const onChange = (event) =&gt; {
      console.log(event.target.value)
      setAmount((current) =&gt; event.target.value)
    }

    const reset = () =&gt; {
      setAmount((current) =&gt; 0)
    }

    // 이 메서드는 위의 메서드와 전혀 다른 값이지만 변수명만 같다.
    // 위에 useState잘보기
    const onfilp = () =&gt; {
      reset()
      setFlipped((current) =&gt; !current)
    }

    return (
      &lt;div&gt;
        &lt;h3&gt;Minutes &amp;&amp; HOURS&lt;/h3&gt;
        &lt;div&gt;
          &lt;label htmlFor=&quot;minutes&quot;&gt;Minutes : &lt;/label&gt;
          &lt;input
            id=&quot;minutes&quot;
            placeholder=&quot;Minutes&quot;
            type=&quot;number&quot;
            value={flipped === true ? amount * 60 : amount}
            onChange={onChange}
            // JSX덕분에 html형식으로 if문 형식을 작동시킬수 있다
            // 뜻 : 만약 flipped가 true이면 disable ={true}이다.
            disabled={flipped === true}
          /&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;label htmlFor=&quot;hours&quot;&gt;Hours : &lt;/label&gt;
          &lt;input
            id=&quot;hours&quot;
            placeholder=&quot;Hours&quot;
            type=&quot;number&quot;
            // flipped === true filp : 키를 눌렀을때
            // Why? --&gt; React.useState(false)로 초기값을 false로 했으니까
            value={flipped === true ? amount : Math.round(amount / 60)}
            onChange={onChange}
            // JSX덕분에 html형식으로 if문 형식을 작동시킬수 있다
            // 뜻 : 만약 flipped가 false이면 disable ={true}이다.
            disabled={flipped === false}
          /&gt;
        &lt;/div&gt;
        &lt;button onClick={reset}&gt;Reset&lt;/button&gt;
        &lt;span&gt; &lt;/span&gt;
        &lt;button onClick={onfilp}&gt;
          {flipped === true ? &#39;분을 시간으로 변환&#39; : &#39;시간을 분으로 변환&#39;}
        &lt;/button&gt;
      &lt;/div&gt;
    )
  }

  function KmToMiles() {
    const [amount, setAmount] = React.useState(0)
    const [flip, setflip] = React.useState(false)

    function onChange(event) {
      setAmount(event.target.value)
    }

    function reset() {
      setAmount((current) =&gt; 0)
    }

    function onfilp() {
      reset()
      setflip((current) =&gt; !current)
    }

    return (
      &lt;div&gt;
        &lt;h3&gt;KM &amp;&amp; Miles&lt;/h3&gt;
        &lt;div&gt;
          &lt;label htmlFor=&quot;km&quot;&gt; km : &lt;/label&gt;
          &lt;input
            id=&quot;km&quot;
            placeholder=&quot;Km&quot;
            type=&quot;number&quot;
            value={flip === false ? amount : amount * 1.609}
            onChange={onChange}
            disabled={flip === true}
          /&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;label htmlFor=&quot;miles&quot;&gt; miles : &lt;/label&gt;
          &lt;input
            id=&quot;miles&quot;
            placeholder=&quot;miles&quot;
            type=&quot;number&quot;
            value={flip === false ? amount / 1.609 : amount}
            onChange={onChange}
            disabled={flip === false}
          /&gt;
        &lt;/div&gt;
        &lt;button onClick={reset}&gt;Reset&lt;/button&gt;
        &lt;button onClick={onfilp}&gt;flip&lt;/button&gt;
      &lt;/div&gt;
    )
  }
  // 분할과 정복(divide&amp;Conquer(분할정복))
  function App() {
    const [index, setIndex] = React.useState(&#39;0&#39;)
    const onSelect = (event) =&gt; {
      console.log(event.target.value)
      setIndex((current) =&gt; event.target.value)
    }
    // return문안에 {}를 쓰고 내용은 JS로 작성할 수있다.
    return (
      &lt;div&gt;
        &lt;h1&gt;Super Converter&lt;/h1&gt;
        &lt;select onChange={onSelect} value={index}&gt;
          &lt;option value=&quot;0&quot;&gt;Minutes To Hours&lt;/option&gt;
          &lt;option value=&quot;1&quot;&gt;Kili To Miles&lt;/option&gt;
        &lt;/select&gt;
        &lt;hr /&gt;
        {index === &#39;0&#39; ? &lt;MinutesToHours /&gt; : null}
        {index === &#39;1&#39; ? &lt;KmToMiles /&gt; : null}
      &lt;/div&gt;
    )
  }
  const root = document.querySelector(&#39;#root&#39;)
  ReactDOM.render(&lt;App /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
&lt;/script&gt;
&lt;/html&gt;
&lt;!-- return문(JSX)안에 {}를 쓰고 내용은 JS로 작성할 수있다. --&gt;
&lt;!-- UseState에서 setVarible을 실행할때 return문에있는 코드를 리렌더링 시킨다 --&gt;
</code></pre>
</li>
</ul>
<!-- <button onClick={reset}>Reset</button> -->
<!-- const reset = (event) => {
    console.log(event.target.value)
    setAmount((current) => 0)
  } -->
<!-- 이 함수(reset)는 입력 요소와 연결되어 있지 않으므로(<button>태그에는 value라는 type이 들어갈수 없다)
      event.target.value 속성을 액세스할 수 없습니다.
     결과적으로 "Reset" 버튼을 클릭할 때 콘솔에서는 undefined 또는 예상치 못한 값이 나타날 수 있습니다.
      이는 reset 함수 내에서 event 객체에 target 속성이 없기 때문입니다. -->

<pre><code>
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[2023.09.06(분할과 정복)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.09.06%EB%B6%84%ED%95%A0%EA%B3%BC-%EC%A0%95%EB%B3%B5</link>
            <guid>https://velog.io/@sago_mungcci/2023.09.06%EB%B6%84%ED%95%A0%EA%B3%BC-%EC%A0%95%EB%B3%B5</guid>
            <pubDate>Thu, 07 Sep 2023 02:17:36 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/7b8ec9c2-86fd-4f49-b3e6-25460f6832fc/image.png" alt=""></p>
<h2 id="definition-access">Definition Access</h2>
<ul>
<li>분할과 정복</li>
</ul>
<p>&quot;분할과 정복&quot;은 한 가지 복잡한 문제를 더 작은 부분으로 나누어 해결하는 전략을 가리키는 말이다. 이 전략은 대개 어려운 문제를 해결할 때 사용되며, 큰 문제를 해결하기 어려운 경우 작은 문제로 쪼개어 해결함으로써 더 효율적으로 해결할 수 있도록 도와준다.</p>
<p>이 전략은 전략적인 마인드셋으로, 많은 분야에서 적용될 수 있다. 예를 들어, 소프트웨어 개발에서는 큰 문제를 작은 모듈로 분할하여 각 모듈을 개발하고 테스트한 다음, 모듈을 결합하여 전체 소프트웨어를 완성하는 방식으로 사용될 수 있다.</p>
<p>또한, 전쟁이나 전략 게임에서도 &quot;분할과 정복&quot; 전략이 사용된다. 상대방의 강력한 세력을 한꺼번에 공격하기보다는 작은 부대로 나눠서 공격하여 상대방을 약화시키는 전략이다.</p>
<p>이러한 방법은 복잡한 문제를 더 쉽게 다룰 수 있게 해주는 강력한 도구로 사용될 수 있다.</p>
<hr>
<h2 id="mechanism">Mechanism</h2>
<ul>
<li><p>전제적인 맥락을 잡고 작게 나누어서 또 나누고 나누어서 개별 모듈을 하나씩 개발하는 방식이다.</p>
</li>
<li><p>아래는 react로 분할과 정복으로 개발한 간단한 예제이다</p>
</li>
<li><p>프로젝트가 커지고 componet가 많아지면 이러한 개발방식은 여러 개발자들이 나누어서 개발하고 이것을 통합시켜서 하나의 프로젝트를 개발할 수 있을것이다.</p>
</li>
</ul>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
  &lt;!-- react import --&gt;
  &lt;!-- &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt; --&gt;
  &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.development.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;
  &lt;!-- babel import(jsx -&gt;react로 변환) --&gt;
  &lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
  &lt;!-- 바벨 사용시 type 입력해주어야 한다. --&gt;
  &lt;script type=&quot;text/babel&quot;&gt;
    const FindMax = ({ nums }) =&gt; {
      const findMax = (arr) =&gt; {
        // 단계 1: 문제를 분할한다.
        if (arr.length === 1) {
          return arr[0]
        }

        const mid = Math.floor(arr.length / 2)
        const left = arr.slice(0, mid)
        const right = arr.slice(mid)

        // 단계 2: 부분 문제를 해결한다.
        const maxLeft = findMax(left)
        const maxRight = findMax(right)

        // 단계 3: 결과를 합친다.
        return Math.max(maxLeft, maxRight)
      }

      const maxNumber = findMax(nums)

      return (
        &lt;div&gt;
          &lt;h3&gt;
            리스트 {nums.join(&#39;, &#39;)}에서 최댓값은 {maxNumber}입니다.
          &lt;/h3&gt;
        &lt;/div&gt;
      )
    }

    const App = () =&gt; {
      const numbers = [3, 8, 1, 6, 2, 8, 5, 9]

      return (
        &lt;div&gt;
          &lt;FindMax nums={numbers} /&gt;
        &lt;/div&gt;
      )
    }

    const root = document.querySelector(&#39;#root&#39;)
    ReactDOM.render(&lt;App /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
  &lt;/script&gt;
&lt;/html&gt;
</code></pre>
<hr>
<h2 id="retrospection">Retrospection</h2>
<ul>
<li><p>내가 니코샘과 개발해온 방식이 분할과 정복으로 해왔다는것을 알게되었다. 이러한 개발방식이 개발시 상당히 도움된다고 생각했고 마음에 들었다.</p>
</li>
<li><p>react에서는 component로 나누어 개발하는 방식이라고하니 코드의 재활용성도 꽤나 효율적일것이라고 생각이 들었다.(한번 제대로 만들었던 코드는 크게 수정할 필요가 없으니.)</p>
</li>
</ul>
<h2 id="--이러한-개발방식은-낮선것이-아니라-우리가-일반적으로-문제에-직면했을때문제를-해결해나갔던-방식이다">- 이러한 개발방식은 낮선것이 아니라 우리가 일반적으로 문제에 직면했을때문제를 해결해나갔던 방식이다.</h2>
<hr>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[2023.09.04(React JS필기 정리)]]></title>
            <link>https://velog.io/@sago_mungcci/2023.09.04React-JS%ED%95%84%EA%B8%B0-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@sago_mungcci/2023.09.04React-JS%ED%95%84%EA%B8%B0-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 04 Sep 2023 09:17:40 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sago_mungcci/post/fbce3f09-dff4-4112-b240-13c34ef0978b/image.jpg" alt=""></p>
<ul>
<li>Nomad Coder - ReactJS로 영화 웹 서비스 만들기</li>
</ul>
<blockquote>
<p>1.reat 설치하거나(terminal로 설치) import하기</p>
</blockquote>
<blockquote>
<p>2.React JS의 규칙 중 하나는 HTML을 이 페이지에 직접 작성하지 않는다.</p>
</blockquote>
<ul>
<li>span,button등의 엘리멘트를 JS로 만든다.</li>
</ul>
<blockquote>
<p>3.html body태그안에 아무것도 없게 되는데 이것을 밀어넣어 주는것이 react dom(<a href="mailto:react-dom@17.0.2">react-dom@17.0.2</a>)이다.</p>
</blockquote>
<ul>
<li>모든 react element들을 html body에 밀어넣어 준다.</li>
</ul>
<blockquote>
<ol start="4">
<li><a href="mailto:react@17.0.2">react@17.0.2</a>는 react Js엔진으로 interactive한 UI를 생성해준다.</li>
</ol>
</blockquote>
<blockquote>
<ol start="5">
<li>바닐라 js에선 html을 먼저 만들고, 그걸 자바스크립트로 가져와서 html을 수정하는 프로세스를 가지고 있다.
 그러나 reactJS에서는 모든것이 자바스크립트로 시작한고 로직 실행후 HTML이 된다. --&gt; 이것이 reactJS의 핵심이다. <ul>
<li>자바스크립트와 리엑트 js를 사용하여 엘리먼트들을 생성할때에는 리엑트JS가 엘리먼트를 생성한다.
이 말은 리엑트JS는 업데이트가 필요한 엘리먼트를 업데이트 할 것이라는 말이다. 즉 리엑트JS에서 바로 HTML을 업데이트할수 있다.</li>
</ul>
</li>
</ol>
</blockquote>
<ul>
<li>바닐라JS<pre><code class="language-html"></code></pre>
</li>
</ul>
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <span>Total Click : 0</span>
    <button id="btn">CntBtn</button>
  </body>
  <script>
    let cnt = 0
    const span = document.querySelector('span')
    const cntBtn = document.querySelector('#btn')

<pre><code>cntBtn.addEventListener(&#39;click&#39;, cntHandler)

function cntHandler() {
  cnt++
  span.innerText = `Total Click : ${cnt}`
}</code></pre><p>  </script></p>
</html>

<pre><code>
- ReactJS(문법 그대로)
```html

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
  &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;script&gt;
    // ** React.createElement()내용을 잘보기

    const root = document.querySelector(&#39;#root&#39;)

    // react로 span태그를 생성
    // 매개변수 순서 (엘리먼트, id or class , contents) 아래 잘보기
    // 여기서 h3이라는 것이 component이다.
    const h3 = React.createElement(
      &#39;h3&#39;,
      //{ id: &#39;sexy-span&#39;, style: { color: &#39;blue&#39; } },
      {
        id: &#39;sexy-span&#39;,
        style: { color: &#39;blue&#39; },
        onMouseEnter: () =&gt; console.log(&#39;mouseEntered&#39;),
      }, // 이부분을 propertys --&gt; props
      &#39;hello reactWorld im span&#39;,
    )
    // react로 button태그를 생성
    const button = React.createElement(
      &#39;button&#39;,
      { onClick: () =&gt; console.log(&#39;im clicked&#39;) },
      &#39;Click me&#39;,
    )

    // react로 생성한 span, button 엘리먼트를 가지고 있는 div태그 생성 --&gt; 배열로 나타내고 있는 것을 잘보자
    const container = React.createElement(&#39;div&#39;, null, [h3, button])
    ReactDOM.render(container, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
  &lt;/script&gt;
&lt;/html&gt;

</code></pre><ul>
<li><p>ReactJS(jsx문법)</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot; /&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
  &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;!-- react import --&gt;
&lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt;
&lt;!-- babel import(jsx -&gt;react로 변환) --&gt;
&lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
&lt;!-- 바벨 사용시 type 입력해주어야 한다. --&gt;
&lt;script type=&quot;text/babel&quot;&gt;
  // ** React.createElement()내용을 잘보기

  const root = document.querySelector(&#39;#root&#39;)

  //jsx --&gt; html의 형식을 그대로 사용해서 html에 밀어넣어주는 react에서 사용 할 수 있는 문법
  //jsx 변수
  /*
   const title = (
     &lt;h3 id=&quot;title&quot; onMouseEnter={() =&gt; console.log(&#39;mouseEntered&#39;)}&gt;
       hello im title
     &lt;/h3&gt;
   )
   */

  /*
   const btn = (
     &lt;button
       style={{ backgroundColor: &#39;tomato&#39; }}
       onClick={() =&gt; console.log(&#39;im clicked&#39;)}
     &gt;
       Click me
     &lt;/button&gt;
   )
    */

  //jsx 함수
  // 아래 2함수는 같은 개념이다.
  function Title() {
    return (
      &lt;h3 id=&quot;title&quot; onMouseEnter={() =&gt; console.log(&#39;mouseEntered&#39;)}&gt;
        hello im title
      &lt;/h3&gt;
    )
  }

  const Btn = () =&gt; (
    &lt;button
      style={{ backgroundColor: &#39;tomato&#39; }}
      onClick={() =&gt; console.log(&#39;im clicked&#39;)}
    &gt;
      Click me
    &lt;/button&gt;
  )
  // ==&gt; title, btn이 reactindex1.html의 h3, button과 같은 코드인데, jsx의 문법을 바로 사용 할 수없다.
  // jsx의 문법을 react로 변환시켜주어야 하는데, babel이라는 라이브러리를 사용해서 변환가능하다.
  // 이것이 이전 강의에서 react로 어렵게 배운이유

  // react로 생성한 span, button 엘리먼트를 가지고 있는 div태그 생성 --&gt; 배열로 나타내고 있는 것을 잘보자
  //const container = React.createElement(&#39;div&#39;, null, [title, btn])
  // const Container = &lt;div&gt;Title, btn&lt;/div&gt; 이렇게 입력하고 렌더링하면 그냥 text인 title, btn이 출력되어 버린다.
  // 이것을 해결하려면 아래와 같은 방식으로 작성하고, 해당 component를 함수로 만들어야 한다.

  // **컴포넌트는 항상 첫글자는 대문자로 입력하자(변수 또한 마찬가지)**
  // -&gt; 우리가 직접 만든 요소는 전부 대문자로 시작해야 함

  const Container = (
    &lt;div&gt;
      &lt;Title /&gt;
      &lt;Btn /&gt;
    &lt;/div&gt;
  )
  //ReactDOM.render(Container, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
  const ContainerMethod = () =&gt; (
    &lt;div&gt;
      &lt;Title /&gt;
      &lt;Btn /&gt;
    &lt;/div&gt;
  )

  // react 문법 + jsx문법
  ReactDOM.render(&lt;ContainerMethod /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
&lt;/script&gt;
&lt;/html&gt;

</code></pre></li>
</ul>
<pre><code>
- ReactJs -State사용 1

```html

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
  &lt;!-- react import --&gt;
  &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;!-- babel import(jsx -&gt;react로 변환) --&gt;
  &lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
  &lt;!-- 바벨 사용시 type 입력해주어야 한다. --&gt;
  &lt;script type=&quot;text/babel&quot;&gt;
    // ** React.createElement()내용을 잘보기

    const root = document.querySelector(&#39;#root&#39;)
    //state : 우리가 클릭할때마다 1씩 증가하는 데이터를 출력해줄 것이다.
    //ReactJS에서 1씩 증가하는 데이터를(값이 변경되는 데이터를) 어떻게 담아줄것인가? --&gt; state
    // render()로 계속 호출하는 것은 최선의 방법이 아니다.
    let countNum = 0
    function countAfter() {
      countNum++
      render()
    }

    function render() {
      ReactDOM.render(&lt;App /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
    }

    const App = () =&gt; (
      &lt;div&gt;
        &lt;h3&gt;Total Click : {countNum}&lt;/h3&gt;
        &lt;button onClick={countAfter}&gt;Click me&lt;/button&gt;
      &lt;/div&gt;
    )
    render()
  &lt;/script&gt;
&lt;/html&gt;

</code></pre><ul>
<li>ReactJs -State사용 2</li>
</ul>
<pre><code class="language-html">
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
  &lt;!-- react import --&gt;
  &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;!-- babel import(jsx -&gt;react로 변환) --&gt;
  &lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
  &lt;!-- 바벨 사용시 type 입력해주어야 한다. --&gt;
  &lt;script type=&quot;text/babel&quot;&gt;
    //state : 우리가 클릭할때마다 1씩 증가하는 데이터를 출력해줄 것이다.
    //ReactJS에서 1씩 증가하는 데이터를(값이 변경되는 데이터를) 어떻게 담아줄것인가? --&gt; state
    // render()로 계속 호출하는 것은 최선의 방법이 아니다.
    // 틀렸다는게 아니다.
    // 하지만 react에서 제공하는 많은 기능들이 있다. 이 기능들을 사용하려면 react의 규칙을 따라야 한다.
    //let counter = 0
    /*
    function countUp() {
      counter++
    }
    */

    // 문법배우기 --&gt; 배열의 요소를 다른이름과 짝지어서 지정해서 그 지정한 이름으로 배열의 요소(값)를 가져올수있다.
    const x = [1, 2, 3]
    const [a, b, c] = x
    console.log(b)

    // react에서는 아래와 같이 함수를 작성할때는 항상 return(엘리먼트)해주어야 하고
    // const variable = () =&gt;() 형식은 return()이 필요없다.
    // const variable = () =&gt;{} 형식은 return()이 필요하다.
    function App() {
      let [counter, setCounter] = React.useState(0)
      // 0,f 나오는데 초기값이 0이고 그다음 뭔가 할수있는 함수를 입력해야한다.
      // 위의 counter변수와 countUp을 해서 계산했던것을 usetState()에서 할수있도록 해놓았다.
      // React.useState()의 매개변수는 2개가 필요하다.
      console.log(counter)

      const onClick = () =&gt; {
        setCounter(counter + 1)
      }

      return (
        &lt;div&gt;
          &lt;h3&gt;Total Click : {counter}&lt;/h3&gt;
          &lt;button onClick={onClick}&gt;Click me&lt;/button&gt;
        &lt;/div&gt;
      )
    }
    const root = document.querySelector(&#39;#root&#39;)
    ReactDOM.render(&lt;App /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
  &lt;/script&gt;
&lt;/html&gt;
</code></pre>
<ul>
<li>ReactJs -State사용 3</li>
</ul>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
  &lt;!-- react import --&gt;
  &lt;script src=&quot;https://unpkg.com/react@17.0.2/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt;
  &lt;!-- babel import(jsx -&gt;react로 변환) --&gt;
  &lt;script src=&quot;https://unpkg.com/@babel/standalone/babel.min.js&quot;&gt;&lt;/script&gt;
  &lt;!-- 바벨 사용시 type 입력해주어야 한다. --&gt;
  &lt;script type=&quot;text/babel&quot;&gt;
    function App() {
      // 바닐라JS가 HTML의 큰틀을 가져와서 기능별로 만들었다면
      // , ReactJS는 이 기능을 더 세부적인 기능(component)으로 나눠서 개발한다.
      let [counter, setCounter] = React.useState(0)

      console.log(counter)

      const onClick = () =&gt; {
        // React.useState() modifier의 2가지 사용법
        // setCounter(counter + 1)

        // modifier에도 함수를 넣을수 있는데, 첫번째 매개변수가 현재 데이터의 값이다.
        // 이것이 좀 더 안전한 방법이다. react에서 현재 어떤 데이터인지 정확히 알수 있다.
        // 따라서 다음에 나올 state의 값이 지금 정확한 현재 값에 기반하여야 한다.
        setCounter((current) =&gt; current + 1)
      }

      return (
        &lt;div&gt;
          &lt;h3&gt;Total Click : {counter}&lt;/h3&gt;
          &lt;button onClick={onClick}&gt;Click me&lt;/button&gt;
        &lt;/div&gt;
      )
    }
    const root = document.querySelector(&#39;#root&#39;)
    ReactDOM.render(&lt;App /&gt;, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
  &lt;/script&gt;
&lt;/html&gt;
</code></pre>
<p>배운점
componenet, usestate, jsx등등 리엑트를 시작하기 위해서 많은 개념들을 배웠다. </p>
<p>그렇지만 니코샘이 강조하였듯이 왜 이런 개념과 규칙이 나왔는지 곰곰히 생각하니, </p>
<p>ReactJS이전에는 html의 큰틀로 나누어 그에 맞는 기능이나 데이터 전달을 JS가 담당했다. 만약 변경해야될 데이터가 많고 특히 자식엘리먼트가 많은경우에는 전부다 다시 변경해줄수 밖에 없을것이다. </p>
<p>만약 50개 태그중 1개의 테그의 값을 변경해주기 위해서 나머지 49개를 다시 업데이트 해야 하는 경우가 있을것이다.(JS로 제어가 불가능하다는 것이 아니라 그만큼 코드량이 많아질것이다.)</p>
<p>그러나 ReactJS를 사용해보니 html의 큰틀로 나누어 그에 맞는 기능이나 데이터 전달하는 기능을 또 나누어서(이게 component개념이 아닌가 싶다.)
굉장히 세분화 시켜서 데이터를 제어할 수있게 되었다. 동시에 그만큼 새로고침 or rerendering할 경우의수도 엄청 줄어들것 같았다. 진짜 강력한 힘이다. </p>
<p>특히 나중에 서버와 연동하여 DB에서 데이터를 가져올때 필요없는 새로고침(rerendering)이 많다면 그만큼 서버는 부담스럽다. 따라서 서버의 리소스를 줄일수있는 가장 효율적인 방법으로 FE를 구축하는게 아닌가 싶다. </p>
<p>막연하게 FE는 디자인이 중요하다고 생각했는데, 디자인도 중요하지만 얼마나 효율적인 공간을 사용하면서 멋지고 아름다운 디자인을 보여주는게 중요하다고 알게 되었다.</p>
<p>ps.
 const x = [1, 2, 3]
 const [a, b, c] = x
 자바를 공부했었던 나는 이걸보고 3분간 멍했다.
 이게...되는구나...</p>
]]></description>
        </item>
    </channel>
</rss>