<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Life goes slowly...</title>
    <link>https://redcow77.tistory.com/</link>
    <description>천천히 가는 삶...</description>
    <language>ko</language>
    <pubDate>Wed, 6 May 2026 16:51:01 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>빨강소</managingEditor>
    <image>
      <title>Life goes slowly...</title>
      <url>https://tistory1.daumcdn.net/tistory/1658201/attach/b765bed38aca432a9da34078f9483094</url>
      <link>https://redcow77.tistory.com</link>
    </image>
    <item>
      <title>[JPA] JPA에서 JpaRepository를 사용하여 쿼리 작성 방법</title>
      <link>https://redcow77.tistory.com/693</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Spring Data JPA에서 JpaRepository를 사용하면서 직접 쿼리를 작성하는 방법은 크게 세 가지가 있다. 단순한 이름 규칙부터 복잡한 동적 쿼리까지 상황에 맞게 선택하시면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-path-to-node=&quot;2&quot; data-ke-size=&quot;size23&quot;&gt;1. 쿼리 메소드 (Query Methods)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;3&quot; data-ke-size=&quot;size16&quot;&gt;가장 간단한 방법입니다. 메소드 이름을 특정 규칙에 맞춰 선언하면 JPA가 이를 해석해 SQL을 자동으로 생성한다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;3&quot; data-ke-size=&quot;size16&quot;&gt;단순조회나 간단한 조건의 쿼리를 사용할때 사용하는 방식이다.(And, Or정도)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;4&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4,0,0&quot;&gt;장점:&lt;/b&gt; 간단함, 별도의 쿼리 작성 불필요.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4,1,0&quot;&gt;단점:&lt;/b&gt; 조건이 많아지면 메소드 이름이 너무 길어짐.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1769818437087&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface UserRepository extends JpaRepository&amp;lt;User, Long&amp;gt; {
    // SELECT * FROM user WHERE email = ?
    Optional&amp;lt;User&amp;gt; findByEmail(String email);

    // SELECT * FROM user WHERE name = ? AND age &amp;gt; ?
    List&amp;lt;User&amp;gt; findByNameAndAgeGreaterThan(String name, int age);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-path-to-node=&quot;7&quot; data-ke-size=&quot;size23&quot;&gt;2. @Query 어노테이션&lt;/h3&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;메소드 위에 직접 JPQL(Java Persistence Query Language)이나 Native SQL을 작성하는 방식이다. 고정된 복잡한 쿼리 나 특정 DB 전용 함수 사용시 사용하는 방식이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;9&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,0,0&quot;&gt;장점:&lt;/b&gt; 복잡한 Join이나 통계 쿼리에 적합, 이름 규칙에서 자유로움.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,1,0&quot;&gt;JPQL:&lt;/b&gt; 엔티티 객체를 대상으로 쿼리 수행.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,2,0&quot;&gt;Native Query:&lt;/b&gt; 특정 DB 전용 SQL을 그대로 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1769818464871&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface UserRepository extends JpaRepository&amp;lt;User, Long&amp;gt; {
    
    // JPQL 사용 (엔티티와 필드 이름 기준)
    @Query(&quot;SELECT u FROM User u WHERE u.status = 'ACTIVE' ORDER BY u.id DESC&quot;)
    List&amp;lt;User&amp;gt; findAllActiveUsers();

    // 파라미터 바인딩 (@Param)
    @Query(&quot;SELECT u FROM User u WHERE u.name = :userName&quot;)
    User findUserByName(@Param(&quot;userName&quot;) String name);

    // Native Query 사용
    @Query(value = &quot;SELECT * FROM users WHERE last_login &amp;gt; DATE_SUB(NOW(), INTERVAL 1 MONTH)&quot;, nativeQuery = true)
    List&amp;lt;User&amp;gt; findRecentLogins();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-path-to-node=&quot;12&quot; data-ke-size=&quot;size23&quot;&gt;3. Querydsl (추천)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;13&quot; data-ke-size=&quot;size16&quot;&gt;코드로 쿼리를 작성하는 방식입니다. 프로젝트 설정이 조금 복잡할 수 있지만, 실무에서는 거의 필수적으로 사용된다. 조건에 따라 쿼리가 변하는 동적 쿼리 그리고 복잡한 Join 사용할때 사용하는 방식이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;14&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;14,0,0&quot;&gt;장점:&lt;/b&gt; &lt;b data-index-in-node=&quot;4&quot; data-path-to-node=&quot;14,0,0&quot;&gt;컴파일 시점에 문법 오류 발견 가능&lt;/b&gt;, 동적 쿼리 작성이 매우 쉬움, 자동 완성 지원.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;14,1,0&quot;&gt;방식:&lt;/b&gt; 보통 CustomRepository를 인터페이스로 만들고 이를 구현(Impl)하여 사용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1769818496743&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Querydsl을 이용한 동적 쿼리 예시 (요약)
public List&amp;lt;User&amp;gt; searchUsers(String name, Integer age) {
    return queryFactory
        .selectFrom(user)
        .where(
            nameEq(name),
            ageEq(age)
        )
        .fetch();
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/Java</category>
      <category>Java</category>
      <category>JPA</category>
      <category>JpaRepository</category>
      <category>querydsl</category>
      <category>Spring</category>
      <category>쿼리메소드</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/693</guid>
      <comments>https://redcow77.tistory.com/693#entry693comment</comments>
      <pubDate>Sat, 31 Jan 2026 09:18:20 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] JPA - ExpressionUtils / 서브쿼리</title>
      <link>https://redcow77.tistory.com/691</link>
      <description>&lt;h1 data-end=&quot;143&quot; data-start=&quot;121&quot;&gt;1. ExpressionUtils란?&lt;/h1&gt;
&lt;p data-end=&quot;230&quot; data-start=&quot;144&quot; data-ke-size=&quot;size16&quot;&gt;ExpressionUtils는 &lt;b&gt;Expression(표현식)을 조합&lt;/b&gt;하거나&lt;br /&gt;&lt;b&gt;서브쿼리를 select 절에 포함&lt;/b&gt;시킬 때 사용하는 유틸입니다.&lt;/p&gt;
&lt;h3 data-end=&quot;240&quot; data-start=&quot;232&quot; data-ke-size=&quot;size23&quot;&gt;주 용도&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;291&quot; data-start=&quot;241&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;257&quot; data-start=&quot;241&quot;&gt;서브쿼리 &amp;rarr; 컬럼처럼 사용&lt;/li&gt;
&lt;li data-end=&quot;268&quot; data-start=&quot;258&quot;&gt;alias 지정&lt;/li&gt;
&lt;li data-end=&quot;291&quot; data-start=&quot;269&quot;&gt;산술 연산용 Expression 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;121&quot; data-end=&quot;143&quot;&gt;2. 서브쿼리 기본 (JPAExpressions)&lt;/h1&gt;
&lt;pre id=&quot;code_1769599580333&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;queryFactory
    .selectFrom(member)
    .where(member.age.gt(
        select(member.age.avg())
            .from(member)
    ))
    .fetch();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;121&quot; data-end=&quot;143&quot;&gt;3. Select 절에 서브쿼리 넣기 (ExpressionUtils.as)&lt;/h1&gt;
&lt;pre id=&quot;code_1769599692942&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;queryFactory
    .select(
        member.username,
        ExpressionUtils.as(
            select(member.age.avg())
                .from(member),
            &quot;avgAge&quot;
        )
    )
    .from(member)
    .fetch();
    
*ExpressionUtils.as(Expression, alias) - alias는 DTO 매핑용&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;143&quot; data-start=&quot;121&quot;&gt;4. 집계 함수 총정리&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QcPbN/dJMcacWdWXl/r47PrjM97DAAdI6ektKEP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QcPbN/dJMcacWdWXl/r47PrjM97DAAdI6ektKEP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QcPbN/dJMcacWdWXl/r47PrjM97DAAdI6ektKEP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQcPbN%2FdJMcacWdWXl%2Fr47PrjM97DAAdI6ektKEP0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;424&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;424&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;121&quot; data-end=&quot;143&quot;&gt;5. 올바른 산술 연산 방법 (NumberExpression)&lt;/h1&gt;
&lt;pre id=&quot;code_1769599906511&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Select 절에서 직접 계산
NumberExpression&amp;lt;Long&amp;gt; expr =
    order.price.sum().subtract(refund.price.sum());

//서브쿼리 + NumberTemplate
NumberExpression&amp;lt;Long&amp;gt; diff =
    Expressions.numberTemplate(
        Long.class,
        &quot;({0}) - ({1})&quot;,
        select(order.price.sum()).from(order),
        select(refund.price.sum()).from(refund)
    );
    

.select(diff)
.from(member)
.fetch();

--서브쿼리 간 뺄셈은 Template 필수&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/Java</category>
      <category>ExpressionUtils</category>
      <category>Java</category>
      <category>JPA</category>
      <category>JPAExpressions</category>
      <category>numbertemplate</category>
      <category>Spring</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/691</guid>
      <comments>https://redcow77.tistory.com/691#entry691comment</comments>
      <pubDate>Fri, 30 Jan 2026 09:36:57 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] JPA + Querydsl 코드 작성방법</title>
      <link>https://redcow77.tistory.com/690</link>
      <description>&lt;h2 data-end=&quot;89&quot; data-start=&quot;72&quot; data-ke-size=&quot;size26&quot;&gt;1. Querydsl이란?&lt;/h2&gt;
&lt;p data-end=&quot;157&quot; data-start=&quot;90&quot; data-ke-size=&quot;size16&quot;&gt;Querydsl은 &lt;b&gt;타입 세이프(Type-safe)&lt;/b&gt; 한 방식으로 JPQL을 작성할 수 있게 해주는 라이브러리입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;249&quot; data-start=&quot;159&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;186&quot; data-start=&quot;159&quot;&gt;문자열 JPQL 사용하지 말것 &amp;rarr; 컴파일 시 오류 미검출&lt;/li&gt;
&lt;li data-end=&quot;218&quot; data-start=&quot;187&quot;&gt;Querydsl 사용 &amp;rarr; 컴파일 타임에 쿼리 오류 검출&lt;/li&gt;
&lt;li data-end=&quot;233&quot; data-start=&quot;219&quot;&gt;동적 쿼리에 매우 강함&lt;/li&gt;
&lt;li data-end=&quot;249&quot; data-start=&quot;234&quot;&gt;JPA와 자연스럽게 결합&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-end=&quot;291&quot; data-start=&quot;256&quot; data-ke-size=&quot;size26&quot;&gt;2. 의존성 설정 (Spring Boot + Gradle)&lt;/h2&gt;
&lt;h3 data-end=&quot;311&quot; data-start=&quot;293&quot; data-ke-size=&quot;size23&quot;&gt;Gradle 설정&lt;/h3&gt;
&lt;pre id=&quot;code_1769598858574&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies {
    implementation 'com.querydsl:querydsl-jpa'
    annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jpa'
    annotationProcessor 'jakarta.persistence:jakarta.persistence-api'
    annotationProcessor 'jakarta.annotation:jakarta.annotation-api'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-end=&quot;653&quot; data-start=&quot;639&quot; data-ke-size=&quot;size26&quot;&gt;3. Q 클래스 생성&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;720&quot; data-start=&quot;654&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;687&quot; data-start=&quot;654&quot;&gt;Entity 기준으로 QEntity 클래스 자동 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1769598971030&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Entity
public class Member {
    @Id @GeneratedValue
    private Long id;
    private String username;
    private int age;
}

-&amp;gt; 생성

QMember member = QMember.member;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-end=&quot;942&quot; data-start=&quot;922&quot; data-ke-size=&quot;size26&quot;&gt;4. Querydsl 기본 설정&lt;/h2&gt;
&lt;h3 data-end=&quot;976&quot; data-start=&quot;944&quot; data-ke-size=&quot;size23&quot;&gt;JPAQueryFactory Bean 등록&lt;/h3&gt;
&lt;pre id=&quot;code_1769599026517&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
public class QuerydslConfig {

    @PersistenceContext
    private EntityManager em;

    @Bean
    public JPAQueryFactory jpaQueryFactory() {
        return new JPAQueryFactory(em);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;922&quot; data-end=&quot;942&quot; data-ke-size=&quot;size26&quot;&gt;5. 기본 조회 쿼리&lt;/h2&gt;
&lt;pre id=&quot;code_1769599247687&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//리스트 조회
public List&amp;lt;Member&amp;gt; findAll() {
    return queryFactory
        .selectFrom(member)
        .fetch();
}


//조건절
private BooleanExpression usernameEq(String username) {
    return username != null ? member.username.eq(username) : null;
}

queryFactory
    .selectFrom(member)
    .where(
        usernameEq(&quot;kim&quot;),
        ageGoe(20)
    )
    .fetch();
    
 //Join 사용
 queryFactory
    .selectFrom(member)
    .join(member.team, team)
    .where(team.name.eq(&quot;개발팀&quot;))
    .fetch();
    

//동적쿼리 - BooleanBuilder
BooleanBuilder builder = new BooleanBuilder();

if (username != null) {
    builder.and(member.username.eq(username));
}

queryFactory
    .selectFrom(member)
    .where(builder)
    .fetch();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Java</category>
      <category>Java</category>
      <category>JPA</category>
      <category>querydsl</category>
      <category>Spring</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/690</guid>
      <comments>https://redcow77.tistory.com/690#entry690comment</comments>
      <pubDate>Thu, 29 Jan 2026 09:21:14 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] JPA ExpressionUtils 서브쿼리로 연산방법</title>
      <link>https://redcow77.tistory.com/692</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; ExpressionUtils로 산술 연산하기&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;❌ &lt;b&gt;잘못된 시도&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769601072735&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ExpressionUtils.as(subQuery1, &quot;a&quot;)
    .subtract(ExpressionUtils.as(subQuery2, &quot;b&quot;));
    
-- ExpressionUtils는 계산용 API가 아니기 때문에 불가능&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 올바른 산술 연산 방법 (NumberExpression)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;- 서브쿼리끼리 &amp;ldquo;계산&amp;rdquo;을 하려면, 각각을 JPAExpressions로 만들고, select 절에서는 ExpressionUtils.as로 alias를 주고, where/조건절에서는 서브쿼리 Expression을 그냥 연산에 넣어서 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;1&quot; style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;기본 개념 정리&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Querydsl(JPA)에서 서브쿼리는 select 절, where 절에서만 사용 가능.&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;select 절:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ExpressionUtils.as(JPAExpressions.select(...), &quot;별칭&quot;)&lt;span&gt;&amp;nbsp;&lt;/span&gt;으로 DTO 필드에 매핑.&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;where 절:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JPAExpressions.select(...)&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 바로 비교/연산에 사용 (ExpressionUtils.as 필요 없음).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 id=&quot;5&quot; style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;패턴 요약&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;ldquo;서브쿼리 뽑아서 DTO 필드로 받고 싶다&amp;rdquo;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ExpressionUtils.as(JPAExpressions.select(...), &quot;필드명&quot;).&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;ldquo;where 절에서 서브쿼리와 컬럼/서브쿼리 비교하고 싶다&amp;rdquo;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컬럼.gt(JPAExpressions.select(...)),&lt;span&gt;&amp;nbsp;&lt;/span&gt;컬럼.between(서브1, 서브2).&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;ldquo;서브쿼리 둘을 계산한 결과를 select로 받고 싶다&amp;rdquo;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;NumberExpression sub1 = JPAExpressions.select(...);&lt;/li&gt;
&lt;li&gt;NumberExpression sub2 = JPAExpressions.select(...);&lt;/li&gt;
&lt;li&gt;ExpressionUtils.as(sub1.subtract(sub2), &quot;필드명&quot;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 id=&quot;4-select&quot; style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;select 절에서 &amp;ldquo;서브쿼리끼리 연산 결과&amp;rdquo; 뽑기&lt;/h2&gt;
&lt;p style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;두 서브쿼리 결과의 차이/합 등을 DTO로 받고 싶다면, 먼저 연산 Expression을 만든 뒤 그걸 ExpressionUtils.as로 감쌉니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1769601361447&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;NumberExpression&amp;lt;Integer&amp;gt; minPrice = JPAExpressions
    .select(orderSub.price.min())
    .from(orderSub);

NumberExpression&amp;lt;Integer&amp;gt; maxPrice = JPAExpressions
    .select(orderSub.price.max())
    .from(orderSub);

// max - min 값(스프레드)을 DTO에 담기
List&amp;lt;PriceSpreadDto&amp;gt; result = queryFactory
    .select(Projections.fields(PriceSpreadDto.class,
        ExpressionUtils.as(
            maxPrice.subtract(minPrice),  // 서브쿼리끼리 연산
            &quot;spread&quot;
        )
    ))
    .from(order)
    .fetch();&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 id=&quot;2-select&quot; style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;select 절: 서브쿼리 뽑고, 별칭 주기&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;첫 번째 인자:&lt;span&gt;&amp;nbsp;&lt;/span&gt;JPAExpressions.select(...)&lt;span&gt;&amp;nbsp;&lt;/span&gt;로 만든 서브쿼리 Expression.&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;두 번째 인자: DTO의 필드명&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;studentCount&quot;.&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 패턴을 반복해서 여러 서브쿼리 값을 DTO에 동시에 넣을 수 있습니다&lt;/p&gt;
&lt;pre id=&quot;code_1769601411862&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public List&amp;lt;AcademyStudentCountDto&amp;gt; findAllStudentCount() {
    return queryFactory
        .select(Projections.fields(AcademyStudentCountDto.class,
            academy.name.as(&quot;academyName&quot;),
            ExpressionUtils.as(               // 서브쿼리 결과에 별칭
                JPAExpressions
                    .select(student.id.count())
                    .from(student)
                    .where(student.academy.eq(academy)),
                &quot;studentCount&quot;
            )
        ))
        .from(academy)
        .fetch();
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 id=&quot;3-where-----between&quot; style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;where 절: 서브쿼리끼리 연산(&amp;gt;, &amp;lt;, between 등)&lt;/h2&gt;
&lt;p style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;where 절에서는 서브쿼리 Expression끼리 바로 연산하면 됩니다.&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 컬럼 vs 서브쿼리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;board.views&lt;span style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;JPAExpressions.select(...).from(...)&lt;span style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;gt&lt;span style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot;&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;goe&lt;span style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot;&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;lt&lt;span style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;등으로 비교.&lt;/span&gt;&lt;span style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-state=&quot;open&quot;&gt;&lt;span data-pplx-citation-url=&quot;https://wildeveloperetrain.tistory.com/174&quot; data-pplx-citation=&quot;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769601480966&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 조회수 &amp;gt; 전체 평균 조회수
List&amp;lt;Board&amp;gt; result = queryFactory
    .selectFrom(board)
    .where(board.views.gt(
        JPAExpressions
            .select(subBoard.views.avg())
            .from(subBoard)
    ))
    .fetch();&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. 서브쿼리 vs 서브쿼리 (예: between)&lt;/h2&gt;
&lt;p style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;서브쿼리 둘을 만들어서 between 등에 넣을 수 있습니다. (DB가 스칼라 서브쿼리 연산을 허용하면 사용 가능)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;between(lower, upper)&lt;span&gt;&amp;nbsp;&lt;/span&gt;에 각각 서브쿼리 Expression을 그대로 넣는 방식입니다.&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: oklch(0.9902 0.004 106.47); color: oklch(0.3039 0.04 213.68); text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다른 예로&lt;span&gt;&amp;nbsp;&lt;/span&gt;gt,&lt;span&gt;&amp;nbsp;&lt;/span&gt;lt,&lt;span&gt;&amp;nbsp;&lt;/span&gt;between,&lt;span&gt;&amp;nbsp;&lt;/span&gt;loe,&lt;span&gt;&amp;nbsp;&lt;/span&gt;goe&lt;span&gt;&amp;nbsp;&lt;/span&gt;등 수치 연산 메서드에 서브쿼리들을 인자로 넘겨서 &amp;ldquo;서브쿼리 간 연산&amp;rdquo;을 표현할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1769601493911&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;NumberExpression&amp;lt;Integer&amp;gt; lower = JPAExpressions
    .select(orderSub.price.min())
    .from(orderSub);

NumberExpression&amp;lt;Integer&amp;gt; upper = JPAExpressions
    .select(orderSub.price.max())
    .from(orderSub);

List&amp;lt;Order&amp;gt; result = queryFactory
    .selectFrom(order)
    .where(order.price.between(lower, upper))
    .fetch();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Java</category>
      <category>ExpressionUtils</category>
      <category>Java</category>
      <category>JPA</category>
      <category>Spring</category>
      <category>연산방법</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/692</guid>
      <comments>https://redcow77.tistory.com/692#entry692comment</comments>
      <pubDate>Wed, 28 Jan 2026 20:59:43 +0900</pubDate>
    </item>
    <item>
      <title>[JPA]JPA 로 개발하면서 자주 하는 실수 Top 5</title>
      <link>https://redcow77.tistory.com/689</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1654&quot; data-origin-height=&quot;1182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ofyof/dJMcad1PLll/9LVoRjIpThTmD2LypeRd21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ofyof/dJMcad1PLll/9LVoRjIpThTmD2LypeRd21/img.png&quot; data-alt=&quot;&amp;amp;lt;출처:grok AI&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ofyof/dJMcad1PLll/9LVoRjIpThTmD2LypeRd21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOfyof%2FdJMcad1PLll%2F9LVoRjIpThTmD2LypeRd21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;465&quot; data-origin-width=&quot;1654&quot; data-origin-height=&quot;1182&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;출처:grok AI&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-path-to-node=&quot;2&quot; data-ke-size=&quot;size26&quot;&gt;JPA 초보자가 자주 하는 실수 Top 5&amp;nbsp;&lt;/h2&gt;
&lt;p data-path-to-node=&quot;3&quot; data-ke-size=&quot;size16&quot;&gt;JPA(Java Persistence API)는 자바 개발자에게 ORM(Object-Relational Mapping)의 강력함을 제공하여 객체 지향적으로 데이터베이스와 상호작용할 수 있게 해줍니다. 하지만 강력한 만큼 제대로 사용하지 않으면 예상치 못한 문제에 부딪힐 수 있습니다. JPA를 처음 접하는 개발자들이 자주 하는 실수 5가지와 이를 피하는 방법을 알아보겠습니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;3&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-path-to-node=&quot;5&quot; data-ke-size=&quot;size23&quot;&gt;1. Entity에 비즈니스 로직 넣기 &amp;rarr; Service로 빼기&lt;/h3&gt;
&lt;p data-path-to-node=&quot;6&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;6&quot;&gt;문제점:&lt;/b&gt; Entity는 데이터베이스 테이블과 매핑되는 순수한 객체여야 합니다. 여기에 비즈니스 로직이 들어가면 Entity의 역할이 모호해지고, 재사용성이 떨어지며, 테스트하기 어려워집니다. Entity는 데이터의 상태를 표현하는 데 집중해야 합니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;6&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;7&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;7&quot;&gt;해결 방안:&lt;/b&gt; 비즈니스 로직은 Service 계층으로 분리해야 합니다. Service 계층은 여러 Entity나 Repository를 조합하여 복잡한 비즈니스 규칙을 처리하는 역할을 합니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;7&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8&quot;&gt;예시:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769297146293&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// bad: Entity에 비즈니스 로직 포함
@Entity
public class Order {
    private int quantity;
    private int price;

    public void calculateTotalPrice() {
        // 비즈니스 로직이 Entity 내부에 존재
        return quantity * price;
    }
}

// good: Service 계층에서 비즈니스 로직 처리
@Service
public class OrderService {
    public int calculateTotalPrice(Order order) {
        return order.getQuantity() * order.getPrice();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1926&quot; data-origin-height=&quot;1838&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V3MSG/dJMcaaD5Eg2/gHxIbqArGlc7OkucbnY98K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V3MSG/dJMcaaD5Eg2/gHxIbqArGlc7OkucbnY98K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V3MSG/dJMcaaD5Eg2/gHxIbqArGlc7OkucbnY98K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV3MSG%2FdJMcaaD5Eg2%2FgHxIbqArGlc7OkucbnY98K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;477&quot; data-origin-width=&quot;1926&quot; data-origin-height=&quot;1838&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-path-to-node=&quot;11&quot; data-ke-size=&quot;size23&quot;&gt;2. Controller에서 Repository 직접 호출 &amp;rarr; Service 거치기&lt;/h3&gt;
&lt;p data-path-to-node=&quot;12&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;12&quot;&gt;문제점:&lt;/b&gt; Controller는 웹 요청을 받고 응답을 반환하는 역할을 합니다. Controller에서 직접 Repository를 호출하면 비즈니스 로직이 Controller에 노출되거나, Controller가 너무 많은 책임을 지게 됩니다. 이는 계층 간의 의존성을 높이고 코드의 응집도를 떨어뜨립니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;12&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;13&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13&quot;&gt;해결 방안:&lt;/b&gt; Controller는 Service 계층을 통해 비즈니스 로직을 위임해야 합니다. Service 계층은 트랜잭션 관리와 비즈니스 로직 처리를 담당하여 Controller의 역할을 가볍게 만듭니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;13&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;14&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;14&quot;&gt;예시:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769297201755&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// bad: Controller에서 Repository 직접 호출
@RestController
public class OrderController {
    @Autowired
    private OrderRepository orderRepository;

    @GetMapping(&quot;/orders/{id}&quot;)
    public Order getOrder(@PathVariable Long id) {
        return orderRepository.findById(id).orElse(null);
    }
}

// good: Controller에서 Service 호출
@RestController
public class OrderController {
    @Autowired
    private OrderService orderService;

    @GetMapping(&quot;/orders/{id}&quot;)
    public OrderDto getOrder(@PathVariable Long id) {
        return orderService.findOrderById(id);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1964&quot; data-origin-height=&quot;1850&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z5KFV/dJMcacIGLhP/90C54Ctkiq2OB6K8myCHK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z5KFV/dJMcacIGLhP/90C54Ctkiq2OB6K8myCHK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z5KFV/dJMcacIGLhP/90C54Ctkiq2OB6K8myCHK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz5KFV%2FdJMcacIGLhP%2F90C54Ctkiq2OB6K8myCHK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;471&quot; data-origin-width=&quot;1964&quot; data-origin-height=&quot;1850&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-path-to-node=&quot;17&quot; data-ke-size=&quot;size23&quot;&gt;3. @Transactional 안 쓰기 &amp;rarr; 데이터 깨짐 위험&lt;/h3&gt;
&lt;p data-path-to-node=&quot;18&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;18&quot;&gt;문제점:&lt;/b&gt; 데이터베이스의 무결성을 유지하기 위해서는 여러 작업이 하나의 논리적인 단위로 묶여 처리되어야 합니다. @Transactional 어노테이션을 사용하지 않으면 각 데이터베이스 작업이 독립적으로 실행되어 데이터 일관성이 깨지거나, 예상치 못한 오류 발생 시 롤백이 되지 않아 데이터가 손상될 수 있습니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;18&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;19&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;19&quot;&gt;해결 방안:&lt;/b&gt; 데이터 변경이 일어나는 모든 Service 메서드에는 @Transactional을 적용해야 합니다. 이를 통해 메서드 내의 모든 데이터베이스 작업이 하나의 트랜잭션으로 묶여 원자성(Atomicity)을 보장받을 수 있습니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;19&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;20&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;20&quot;&gt;예시:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769297232814&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// bad: @Transactional 없이 데이터 변경
@Service
public class ProductService {
    @Autowired
    private ProductRepository productRepository;

    public void updateProductPrice(Long productId, int newPrice) {
        Product product = productRepository.findById(productId).orElseThrow();
        product.setPrice(newPrice);
        // save를 호출해도 트랜잭션 범위가 아니므로 예외 발생 시 롤백 안됨
    }
}

// good: @Transactional 적용
@Service
@Transactional
public class ProductService {
    @Autowired
    private ProductRepository productRepository;

    public void updateProductPrice(Long productId, int newPrice) {
        Product product = productRepository.findById(productId).orElseThrow();
        product.setPrice(newPrice);
        // 트랜잭션 내에서 처리되므로 안정성 보장
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;1820&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjdJiU/dJMcacPshCC/ZJz7jXTEg0oQiUs6gKyne0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjdJiU/dJMcacPshCC/ZJz7jXTEg0oQiUs6gKyne0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjdJiU/dJMcacPshCC/ZJz7jXTEg0oQiUs6gKyne0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjdJiU%2FdJMcacPshCC%2FZJz7jXTEg0oQiUs6gKyne0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;480&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;1820&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-path-to-node=&quot;23&quot; data-ke-size=&quot;size23&quot;&gt;4. Entity를 그대로 Response로 주기 &amp;rarr; DTO로 변환 필수&lt;/h3&gt;
&lt;p data-path-to-node=&quot;24&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;24&quot;&gt;문제점:&lt;/b&gt; Entity는 애플리케이션의 핵심 비즈니스 로직과 밀접하게 연관되어 있으며, 데이터베이스의 구조를 반영합니다. Entity를 HTTP 응답으로 직접 반환하면 다음과 같은 문제가 발생할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;25&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;25,0,0&quot;&gt;보안 문제:&lt;/b&gt; 민감한 정보(예: 비밀번호, 내부 ID)가 외부에 노출될 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;25,1,0&quot;&gt;유연성 부족:&lt;/b&gt; Entity의 필드가 변경될 때마다 API 스펙도 변경되어야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;25,2,0&quot;&gt;불필요한 데이터 전송:&lt;/b&gt; 클라이언트에게 필요 없는 필드까지 함께 전송되어 네트워크 오버헤드가 발생합니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;25,3,0&quot;&gt;무한 재귀 참조:&lt;/b&gt; 양방향 연관관계가 있는 Entity의 경우 JSON 직렬화 시 무한 루프가 발생할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-path-to-node=&quot;26&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;26&quot;&gt;해결 방안:&lt;/b&gt; 클라이언트에게 데이터를 반환할 때는 항상 DTO(Data Transfer Object)로 변환하여 사용해야 합니다. DTO는 클라이언트에게 필요한 데이터만 포함하며, API 스펙을 Entity와 분리하여 관리할 수 있게 해줍니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;26&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;27&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;27&quot;&gt;예시:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769297267390&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// bad: Entity를 직접 반환
@RestController
public class UserController {
    @Autowired
    private UserRepository userRepository;

    @GetMapping(&quot;/users/{id}&quot;)
    public User getUser(@PathVariable Long id) {
        return userRepository.findById(id).orElse(null); // User Entity 반환
    }
}

// good: DTO로 변환하여 반환
public class UserDto {
    private String name;
    private String email;
    // ... 필요한 필드만 포함
}

@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping(&quot;/users/{id}&quot;)
    public UserDto getUser(@PathVariable Long id) {
        return userService.findUserDtoById(id); // UserDto 반환
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1954&quot; data-origin-height=&quot;1800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7JE8Y/dJMcadtZCbm/xo4gKHPzqQI6R3l9774v2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7JE8Y/dJMcadtZCbm/xo4gKHPzqQI6R3l9774v2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7JE8Y/dJMcadtZCbm/xo4gKHPzqQI6R3l9774v2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7JE8Y%2FdJMcadtZCbm%2Fxo4gKHPzqQI6R3l9774v2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;461&quot; data-origin-width=&quot;1954&quot; data-origin-height=&quot;1800&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-path-to-node=&quot;23&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-path-to-node=&quot;23&quot; data-ke-size=&quot;size23&quot;&gt;5. 모든 메서드에 @Transactionsal(readOnly = true) 를 쓰지 않는것&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b data-path-to-node=&quot;24&quot; data-index-in-node=&quot;0&quot;&gt;문제점:&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; 조회 전용 메서드임에도 불구하고 불필요한 스냅샷 생성하여 Dirty Checking 비용이 발생한다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b data-path-to-node=&quot;26&quot; data-index-in-node=&quot;0&quot;&gt;해결 방안:&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; 조회용 메서드는 반드시 readOnly를 붙이는 습관을 갖고 개발을 진행하는것이 좋다. 이로써 성능의 차이가 20~50% 이상 나는 경우도 흔하다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b data-path-to-node=&quot;27&quot; data-index-in-node=&quot;0&quot;&gt;예시:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769297719670&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 읽기 메서드인데 readOnly = true 없음 &amp;rarr; 불필요한 dirty checking, 2nd level cache 활용 못 함
public List&amp;lt;Order&amp;gt; findRecentOrders() { ... }

// 반대로 모든 메서드에 readOnly = true 붙여놓고 중요한 쓰기 메서드도 그대로 &amp;rarr; 데이터 안 저장됨

//추천하는 설정방법
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class OrderQueryService {

    // 대부분의 메서드는 readOnly 그대로 사용

    @Transactional
    public void someModifyMethod() { ... }   // 필요한 곳에만 override
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Java</category>
      <category>Entity</category>
      <category>Java</category>
      <category>JPA</category>
      <category>JPA개발실수</category>
      <category>Repository</category>
      <category>Spring</category>
      <category>TRANSACTIONAL</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/689</guid>
      <comments>https://redcow77.tistory.com/689#entry689comment</comments>
      <pubDate>Tue, 27 Jan 2026 09:41:45 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] JPA 핵심 개념 5가지!!!</title>
      <link>https://redcow77.tistory.com/688</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;JPA의 핵심 개념 5가지 !!! - 이것만 알고 있어도 절반은 이해하고 개발을 할수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JPA&amp;nbsp;핵심&amp;nbsp;개념&amp;nbsp;5가지&amp;nbsp;-&amp;nbsp;Entity,&amp;nbsp;EntityManager&amp;nbsp;,&amp;nbsp;Repository,&amp;nbsp;Persistence&amp;nbsp;Context,&amp;nbsp;Transaction&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Gemini_Generated_Image_h3gtmnh3gtmnh3gt.png&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdVCzo/dJMcacWcpMc/JIHwKswVCxDaJLVWvvu1bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdVCzo/dJMcacWcpMc/JIHwKswVCxDaJLVWvvu1bk/img.png&quot; data-alt=&quot;&amp;amp;lt;출처:gemini&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdVCzo/dJMcacWcpMc/JIHwKswVCxDaJLVWvvu1bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdVCzo%2FdJMcacWcpMc%2FJIHwKswVCxDaJLVWvvu1bk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1408&quot; height=&quot;768&quot; data-filename=&quot;Gemini_Generated_Image_h3gtmnh3gtmnh3gt.png&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;출처:gemini&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;628&quot; data-start=&quot;610&quot; data-ke-size=&quot;size23&quot;&gt;① Entity (엔티티)&lt;/h3&gt;
&lt;h3 data-end=&quot;628&quot; data-start=&quot;610&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;DB 테이블과 1:1로 매핑되는 Java 클래스&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1769262371321&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Entity
public class Member {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4,0,0&quot;&gt;정의:&lt;/b&gt; 데이터베이스의 테이블과 매핑(연결)되는 자바 클래스입니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4,1,0&quot;&gt;역할:&lt;/b&gt; 실제 데이터가 담겨 있는 객체입니다. 이 클래스의 인스턴스(객체) 하나는 데이터베이스 테이블의 한 행(Row)에 해당합니다. 개발자는 이 객체를 생성하고 데이터를 채워서 JPA에게 넘겨주게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-end=&quot;859&quot; data-start=&quot;830&quot; data-ke-size=&quot;size23&quot;&gt;② EntityManager (엔티티 매니저)&lt;/h3&gt;
&lt;h3 data-end=&quot;859&quot; data-start=&quot;830&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; font-size: 16px; letter-spacing: 0px;&quot;&gt;JPA의 핵심 객체, &lt;/span&gt;&lt;b&gt;DB와 대화하는 창구&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;944&quot; data-start=&quot;891&quot; data-ke-size=&quot;size16&quot;&gt;하지만 Spring에서는 직접 쓰진 않지만 대신 &lt;b&gt;Repository&lt;/b&gt;를 사용합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;6,0,0&quot;&gt;정의:&lt;/b&gt; 엔티티의 생명주기를 관리하는 주체입니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;6,1,0&quot;&gt;역할:&lt;/b&gt; 이름 그대로 엔티티를 '관리'하는 객체입니다. 개발자가 데이터베이스에 데이터를 저장(persist), 조회(find), 삭제(remove)하고 싶을 때, 이 엔티티 매니저의 메서드를 호출하여 작업을 요청합니다. 영속성 컨텍스트와 상호작용하며 실질적인 CRUD(생성, 조회, 수정, 삭제) 작업을 처리합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-end=&quot;967&quot; data-start=&quot;951&quot; data-ke-size=&quot;size23&quot;&gt;③ Repository&lt;/h3&gt;
&lt;h3 data-end=&quot;967&quot; data-start=&quot;951&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; font-size: 16px; letter-spacing: 0px;&quot;&gt;DB 작업을 대신 해주는 인터페이스&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1769262346874&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface MemberRepository 
        extends JpaRepository&amp;lt;Member, Long&amp;gt; {
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1110&quot; data-start=&quot;1087&quot; data-ke-size=&quot;size16&quot;&gt;이 한 줄로 기능이 자동 제공됩니다.&amp;nbsp; -&amp;gt; &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;save(), &lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;findById(),&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;findAll(),&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;delete()&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;12,0,0&quot;&gt;정의:&lt;/b&gt; 데이터 접근 계층(DAO)을 추상화한 인터페이스입니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;12,1,0&quot;&gt;역할:&lt;/b&gt; Spring 프레임워크에서 JPA를 더 쉽게 사용할 수 있도록 제공하는 기능입니다. 개발자가 복잡한 EntityManager를 직접 다루는 대신, Repository 인터페이스를 상속받아 save(), findById() 같은 직관적인 메서드만 호출하면 Spring이 내부적으로 EntityManager를 사용하여 적절한 데이터베이스 작업을 수행합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-end=&quot;1224&quot; data-start=&quot;1188&quot; data-ke-size=&quot;size23&quot;&gt;④ Persistence Context (영속성 컨텍스트) ⭐ 핵심 개념&lt;/h3&gt;
&lt;h3 data-end=&quot;1224&quot; data-start=&quot;1188&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; font-size: 16px; letter-spacing: 0px;&quot;&gt;JPA의 &lt;/span&gt;&lt;b&gt;1차 캐시 + 객체 관리 공간&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1261&quot; data-start=&quot;1254&quot; data-ke-size=&quot;size16&quot;&gt;중요한 특징:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1320&quot; data-start=&quot;1262&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1294&quot; data-start=&quot;1262&quot;&gt;같은 ID 조회 &amp;rarr; &lt;b&gt;DB 안 가고 캐시에서 반환&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1320&quot; data-start=&quot;1295&quot;&gt;객체 값 변경 &amp;rarr; &lt;b&gt;자동 UPDATE&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1769262322216&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;member.setName(&quot;변경됨&quot;);
// save() 안 해도 트랜잭션 끝나면 자동 반영&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,0,0&quot;&gt;정의:&lt;/b&gt; 엔티티를 영구 저장하는 환경이라는 뜻으로, 엔티티 매니저가 엔티티를 관리하는 **임시 메모리 공간(1차 캐시)**입니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,1,0&quot;&gt;역할:&lt;/b&gt; JPA의 가장 중요한 특징으로, 애플리케이션과 데이터베이스 사이에서 버퍼 역할을 합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;8,1,1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,1,1,0,0&quot;&gt;1차 캐시:&lt;/b&gt; 데이터를 조회할 때 데이터베이스에 바로 접근하기 전에 이곳을 먼저 확인하여 성능을 높입니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,1,1,1,0&quot;&gt;변경 감지(Dirty Checking):&lt;/b&gt; 이곳에 관리되는 엔티티의 데이터가 변경되면, JPA가 이를 자동으로 감지하여 별도의 업데이트(update) 호출 없이도 데이터베이스에 변경 사항을 반영합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-end=&quot;1448&quot; data-start=&quot;1424&quot; data-ke-size=&quot;size23&quot;&gt;⑤ Transaction (트랜잭션)&lt;/h3&gt;
&lt;h3 data-end=&quot;1448&quot; data-start=&quot;1424&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; font-size: 16px; letter-spacing: 0px;&quot;&gt;작업의 &lt;/span&gt;&lt;b&gt;하나의 묶음&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;1614&quot; data-end=&quot;1672&quot;&gt;
&lt;li data-start=&quot;1614&quot; data-end=&quot;1632&quot;&gt;메서드 시작 &amp;rarr; 트랜잭션 시작&lt;/li&gt;
&lt;li data-start=&quot;1633&quot; data-end=&quot;1653&quot;&gt;메서드 종료 &amp;rarr; 자동 commit&lt;/li&gt;
&lt;li data-start=&quot;1654&quot; data-end=&quot;1672&quot;&gt;예외 발생 &amp;rarr; rollback&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1769262300369&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Transactional
public void updateName(Long id) {
    Member member = repository.findById(id).get();
    member.setName(&quot;new name&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;10,0,0&quot;&gt;정의:&lt;/b&gt; 데이터베이스 작업의 논리적인 실행 단위입니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;10,1,0&quot;&gt;역할:&lt;/b&gt; 여러 단계의 데이터베이스 작업을 하나의 묶음으로 처리합니다. 이 묶음 안의 모든 작업이 성공적으로 끝나야 데이터베이스에 결과가 영구적으로 반영(Commit)되며, 중간에 하나라도 실패하면 모든 작업이 처음 상태로 되돌아갑니다(Rollback). JPA의 모든 데이터 변경 작업은 반드시 트랜잭션 안에서 이루어져야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Java</category>
      <category>Java</category>
      <category>JPA</category>
      <category>Repository</category>
      <category>Spring</category>
      <category>Transaction</category>
      <category>핵심5가지</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/688</guid>
      <comments>https://redcow77.tistory.com/688#entry688comment</comments>
      <pubDate>Mon, 26 Jan 2026 10:50:09 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] 초보자가 쉽게 이해하는 JPA 동작구조</title>
      <link>https://redcow77.tistory.com/687</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;JPA 동작구조.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d02K4g/dJMcagjZ9TM/bJn5OkIbOIcFrU06lELOZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d02K4g/dJMcagjZ9TM/bJn5OkIbOIcFrU06lELOZ1/img.png&quot; data-alt=&quot;&amp;amp;lt;출처:gemini&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d02K4g/dJMcagjZ9TM/bJn5OkIbOIcFrU06lELOZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd02K4g%2FdJMcagjZ9TM%2FbJn5OkIbOIcFrU06lELOZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;650&quot; data-filename=&quot;JPA 동작구조.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;출처:gemini&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;18&quot; data-path-to-node=&quot;0&quot;&gt;JPA가 코드 내부적으로 데이터를 관리와 데이터베이스와 소통&lt;/b&gt; 핵심 구성 요소를 동작구조에 대해서 설명하도록 하겠습니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;1&quot; data-ke-size=&quot;size16&quot;&gt;JPA의 동작 구조를 이해할 때 가장 중요한 것은 **'영속성 컨텍스트(Persistence Context)'**라는 입니다.&lt;/p&gt;
&lt;hr data-path-to-node=&quot;2&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-path-to-node=&quot;3&quot; data-ke-size=&quot;size23&quot;&gt;1. JPA의 핵심 구성 요소&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;4&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4,0,0&quot;&gt;EntityManagerFactory (공장):&lt;/b&gt; 딱 한 번만 만들어지는 커다란 공장입니다. 애플리케이션이 실행될 때 생성되어 DB 연결 정보 등을 준비합니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4,1,0&quot;&gt;EntityManager (일꾼):&lt;/b&gt; 고객의 요청(트랜잭션)이 올 때마다 공장에서 파견되는 일꾼입니다. DB에 저장하거나 수정하는 모든 일을 이 일꾼이 처리합니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4,2,0&quot;&gt;Persistence Context (영속성 컨텍스트):&lt;/b&gt; 일꾼이 들고 다니는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;*임시 메모리 저장소(장바구니)*&lt;/b&gt;&lt;/span&gt;입니다. 자바 객체를 DB에 바로 던지기 전에 여기에 먼저 담아둡니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-path-to-node=&quot;6&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-path-to-node=&quot;6&quot; data-ke-size=&quot;size23&quot;&gt;2. JPA의 동작 과정 (데이터 저장 예시)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;7&quot; data-ke-size=&quot;size16&quot;&gt;우리가 자바 코드에서 em.persist(user)라고 명령을 내리면 다음과 같은 일이 일어납니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-path-to-node=&quot;8&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,0,0&quot;&gt;1차 캐시에 저장:&lt;/b&gt; 객체(User)가 DB로 바로 가는 게 아니라, 영속성 컨텍스트 내부의 **'1차 캐시'**에 먼저 저장됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,1,0&quot;&gt;쓰기 지연 SQL 저장소:&lt;/b&gt; JPA는 바로 INSERT 쿼리를 날리지 않고, 전송할 SQL 문을 차곡차곡 쌓아둡니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,2,0&quot;&gt;트랜잭션 커밋 (플러시):&lt;/b&gt; 작업이 다 끝나고 commit을 하는 순간, 쌓아뒀던 쿼리들을 DB에 한꺼번에 보냅니다. (이것을 &lt;b data-index-in-node=&quot;70&quot; data-path-to-node=&quot;8,2,0&quot;&gt;쓰기 지연&lt;/b&gt;이라고 합니다.)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-path-to-node=&quot;10&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-path-to-node=&quot;10&quot; data-ke-size=&quot;size23&quot;&gt;3. 왜 이런 복잡한 구조를 가질까요?&amp;nbsp;&lt;/h3&gt;
&lt;p data-path-to-node=&quot;11&quot; data-ke-size=&quot;size16&quot;&gt;이런 '장바구니(영속성 컨텍스트)' 구조 덕분에 자바 개발자는 장점을 가지게 됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;12&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;12,0,0&quot;&gt;1차 캐시 (조회 성능 향상):&lt;/b&gt; 똑같은 데이터를 두 번 조회하면, DB에 가지 않고 메모리(1차 캐시)에서 바로 꺼내옵니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;12,1,0&quot;&gt;변경 감지 (Dirty Checking):&lt;/b&gt; 데이터를 수정할 때 별도의 update() 메서드를 호출할 필요가 없습니다. 자바 객체의 값만 바꾸고 커밋하면, JPA가 처음 상태와 비교해서 &lt;b data-index-in-node=&quot;104&quot; data-path-to-node=&quot;12,1,0&quot;&gt;알아서 UPDATE 쿼리&lt;/b&gt;를 날려줍니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;12,2,0&quot;&gt;동일성 보장:&lt;/b&gt; 같은 ID로 조회한 객체는 자바 코드 상에서 항상 같은 객체(== 비교 시 true)임을 보장합니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>프로그래밍/Java</category>
      <category>GEMINI</category>
      <category>Java</category>
      <category>JPA</category>
      <category>Jpa동작구조</category>
      <category>Spring</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/687</guid>
      <comments>https://redcow77.tistory.com/687#entry687comment</comments>
      <pubDate>Sun, 25 Jan 2026 09:43:23 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] 초보자가 쉽게 이해하는 Spring Data JPA 설명</title>
      <link>https://redcow77.tistory.com/686</link>
      <description>&lt;p data-path-to-node=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;초보자도&amp;nbsp; 쉽게 이해하는 Spring Data JPA에 대해 설명해 드릴게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 각 용어가 의미하는 내용에 대해서 설명이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J8cgZ/dJMcafZGqqv/EdukvJty06VQtmAGX1a2tK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J8cgZ/dJMcafZGqqv/EdukvJty06VQtmAGX1a2tK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J8cgZ/dJMcafZGqqv/EdukvJty06VQtmAGX1a2tK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ8cgZ%2FdJMcafZGqqv%2FEdukvJty06VQtmAGX1a2tK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1209&quot; height=&quot;387&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;387&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-path-to-node=&quot;1&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-path-to-node=&quot;1&quot; data-ke-size=&quot;size23&quot;&gt;1. JPA가 없을 때의 문제점&lt;/h3&gt;
&lt;p data-path-to-node=&quot;2&quot; data-ke-size=&quot;size16&quot;&gt;옛날에는 자바 애플리케이션에서 데이터베이스에 데이터를 저장하거나 가져오려면, 개발자가 직접 복잡한 SQL 쿼리문을 하나하나 작성해야 했습니다. 마치 서로 다른 언어를 사용하는 두 사람 사이에 통역사가 없는 것과 같아서, 개발자는 SQL이라는 낯선 언어와 씨름하며 머리를 싸매야 했죠.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;JPA-1.png&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0t4OQ/dJMcac9GBMY/jDgnthFrpT3g0IG2kVNFA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0t4OQ/dJMcac9GBMY/jDgnthFrpT3g0IG2kVNFA0/img.png&quot; data-alt=&quot;&amp;amp;lt;출처 : gemini&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0t4OQ/dJMcac9GBMY/jDgnthFrpT3g0IG2kVNFA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0t4OQ%2FdJMcac9GBMY%2FjDgnthFrpT3g0IG2kVNFA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1408&quot; height=&quot;768&quot; data-filename=&quot;JPA-1.png&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;출처 : gemini&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1769210481090&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//기존 JDBC와 SQL 방식

Java 코드
  &amp;darr;
SQL 작성
  &amp;darr;
DB 실행
  &amp;darr;
ResultSet
  &amp;darr;
Java 객체로 변환&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-path-to-node=&quot;4&quot; data-ke-size=&quot;size23&quot;&gt;2. JPA: 자바와 데이터베이스의 다리&lt;/h3&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;**JPA(Java Persistence API)**는 이런 문제를 해결해주는 '다리' 또는 '통역사' 역할을 합니다. JPA를 사용하면 개발자는 자바 객체(Object)를 다루듯이 코드를 작성하고, JPA가 알아서 이 코드를 데이터베이스가 이해할 수 있는 SQL로 번역해줍니다. 덕분에 개발자는 복잡한 SQL에서 해방되어 자바 코드에만 집중할 수 있게 되었죠.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;JPA-2.png&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p1TpL/dJMb99ZufEd/i5kGCB0PXqzVM7tKkIsN1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p1TpL/dJMb99ZufEd/i5kGCB0PXqzVM7tKkIsN1K/img.png&quot; data-alt=&quot;&amp;amp;lt;출처 : gemini&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p1TpL/dJMb99ZufEd/i5kGCB0PXqzVM7tKkIsN1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp1TpL%2FdJMb99ZufEd%2Fi5kGCB0PXqzVM7tKkIsN1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1408&quot; height=&quot;768&quot; data-filename=&quot;JPA-2.png&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;출처 : gemini&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-path-to-node=&quot;7&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-path-to-node=&quot;7&quot; data-ke-size=&quot;size23&quot;&gt;3. Spring Data JPA: 더 쉽고 간편하게&lt;/h3&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8&quot;&gt;Spring Data JPA&lt;/b&gt;는 JPA를 더욱 쉽고 편리하게 사용할 수 있도록 도와주는 Spring 프레임워크의 일부입니다. JPA라는 다리 위에 '자동 운전 시스템'을 하나 더 얹은 것과 같습니다. 개발자는 save(), findAll(), findById()처럼 직관적인 이름의 메서드만 호출하면, Spring Data JPA가 알아서 적절한 JPA 코드를 실행하고 데이터베이스와 통신합니다. 복잡한 설정이나 반복적인 코드를 획기적으로 줄여주어 개발 생산성을 크게 높여줍니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;JPA-3.png&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/F5oAO/dJMcaiIQteS/BCYk9eBdYvdWlJOhkYdQK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/F5oAO/dJMcaiIQteS/BCYk9eBdYvdWlJOhkYdQK0/img.png&quot; data-alt=&quot;&amp;amp;lt;출처 : gemini&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/F5oAO/dJMcaiIQteS/BCYk9eBdYvdWlJOhkYdQK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FF5oAO%2FdJMcaiIQteS%2FBCYk9eBdYvdWlJOhkYdQK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1408&quot; height=&quot;768&quot; data-filename=&quot;JPA-3.png&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;출처 : gemini&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1769210616778&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//JPA 사용시(SQL 사용하지 않고 객체저장/조회만 하면됨)

Java 객체
  &amp;darr;
JPA
  &amp;darr;
DB&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-path-to-node=&quot;10&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;10&quot;&gt;요약하자면:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;11&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,0,0&quot;&gt;과거:&lt;/b&gt; 자바와 DB 사이의 소통이 어려워 개발자가 직접 복잡한 SQL을 작성해야 했습니다. (첫 번째 이미지)&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,1,0&quot;&gt;JPA:&lt;/b&gt; 자바와 DB 사이를 연결해주는 '다리' 역할을 하여, 자바 코드를 SQL로 자동 번역해줍니다. (두 번째 이미지)&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,2,0&quot;&gt;Spring Data JPA:&lt;/b&gt; JPA를 더 쉽게 사용할 수 있도록 도와주는 도구로, 간단한 메서드 호출만으로 DB 작업을 처리할 수 있게 해줍니다. (세 번째 이미지)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-path-to-node=&quot;12&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 JPA와 Spring Data JPA 덕분에 개발자는 복잡한 데이터베이스 작업에서 벗어나, 애플리케이션의 핵심 로직을 만드는 데 더 집중할 수 있게 되었습니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;12&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Java</category>
      <category>Java</category>
      <category>JPA</category>
      <category>Spring</category>
      <category>spring boot</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/686</guid>
      <comments>https://redcow77.tistory.com/686#entry686comment</comments>
      <pubDate>Sat, 24 Jan 2026 08:27:18 +0900</pubDate>
    </item>
    <item>
      <title>전산세무 2급 - 이론 정리</title>
      <link>https://redcow77.tistory.com/685</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;  전산세무 2급 기출 요약 암기노트 (이론 위주 핵심 정리)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;전산세무 2급 핵심 이론 완벽 정리  &lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전산세무 2급 자격증은 재무회계, 원가회계, 세무회계(부가가치세, 소득세)에 대한 이론적 지식과 실무 능력을 평가하는 시험입니다. 이론 시험(30%)과 실무 시험(70%)으로 구성되며, 합격을 위해서는 각 과목의 핵심 개념을 정확히 이해하는 것이 중요합니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Ⅰ. 재무회계 (Financial Accounting)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재무회계는 기업 외부의 정보이용자(주주, 채권자 등)에게 유용한 정보를 제공하기 위해 재무제표를 작성하고 보고하는 것을 목적으로 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;주요 개념:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;재무제표의 기본 가정&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;기업실체의 가정&lt;/b&gt;: 기업은 소유주와는 독립적으로 존재하는 회계단위로 간주합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;계속기업의 가정&lt;/b&gt;: 기업은 예측 가능한 기간 동안 영업활동을 계속할 것이라고 가정합니다. 이는 감가상각, 자산&amp;middot;부채의 유동성 분류 등의 근거가 됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기간별 보고의 가정&lt;/b&gt;: 기업의 전체 존속기간을 일정한 기간(보통 1년)으로 분할하여 각 기간의 재무정보를 보고합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;재무제표의 질적 특성&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;목적적합성&lt;/b&gt;: 정보이용자의 의사결정에 차이를 가져올 수 있는 능력 (예측가치, 확인가치, 중요성).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;신뢰성&lt;/b&gt;: 정보가 나타내고자 하는 바를 충실하게 표현하고, 중립적이며, 검증 가능해야 함 (표현의 충실성, 중립성, 검증가능성).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자산&amp;middot;부채&amp;middot;자본&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;유동자산&lt;/b&gt;: 1년 이내에 현금화될 수 있는 자산으로 &lt;b&gt;당좌자산&lt;/b&gt;(현금및현금성자산, 단기매매증권, 매출채권 등)과 &lt;b&gt;재고자산&lt;/b&gt;으로 구분됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비유동자산&lt;/b&gt;: 1년 이후에 현금화되는 자산으로 &lt;b&gt;투자자산&lt;/b&gt;, &lt;b&gt;유형자산&lt;/b&gt;, &lt;b&gt;무형자산&lt;/b&gt;, &lt;b&gt;기타비유동자산&lt;/b&gt;으로 구성됩니다. 특히, 무형자산(영업권, 개발비 등)의 인식 요건과 상각 방법을 이해하는 것이 중요합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;부채&lt;/b&gt;: &lt;b&gt;유동부채&lt;/b&gt;(매입채무, 미지급금, 단기차입금 등)와 &lt;b&gt;비유동부채&lt;/b&gt;(사채, 장기차입금, 퇴직급여충당부채 등)로 나뉩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자본&lt;/b&gt;: &lt;b&gt;자본금&lt;/b&gt;, &lt;b&gt;자본잉여금&lt;/b&gt;, &lt;b&gt;자본조정&lt;/b&gt;, &lt;b&gt;기타포괄손익누계액&lt;/b&gt;, &lt;b&gt;이익잉여금&lt;/b&gt;으로 구분됩니다. 각 항목의 발생 원인(증자, 감자, 주식배당 등)을 명확히 알아야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;수익과 비용&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;매출총이익&lt;/b&gt; = 매출액 - 매출원가&lt;/li&gt;
&lt;li&gt;&lt;b&gt;영업이익&lt;/b&gt; = 매출총이익 - 판매비와관리비&lt;/li&gt;
&lt;li&gt;&lt;b&gt;법인세비용차감전순이익&lt;/b&gt; = 영업이익 + 영업외수익 - 영업외비용&lt;/li&gt;
&lt;li&gt;수익은 실현주의, 비용은 수익&amp;middot;비용 대응의 원칙에 따라 인식합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Ⅱ. 원가회계 (Cost Accounting)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원가회계는 제품 제조에 소요된 원가를 계산하고, 경영자의 의사결정에 필요한 원가 정보를 제공하는 것을 목표로 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;주요 개념:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;원가의 분류&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;발생 형태별&lt;/b&gt;: 재료비, 노무비, 경비&lt;/li&gt;
&lt;li&gt;&lt;b&gt;추적 가능성별&lt;/b&gt;: &lt;b&gt;직접비&lt;/b&gt;(특정 제품에 직접 추적 가능)와 &lt;b&gt;간접비&lt;/b&gt;(여러 제품에 공통으로 발생하여 배부 필요)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;원가 행태별&lt;/b&gt;: &lt;b&gt;변동비&lt;/b&gt;(조업도 변동에 비례하여 총원가 변동)와 &lt;b&gt;고정비&lt;/b&gt;(조업도 변동과 관계없이 총원가 일정)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;원가 배분&lt;/b&gt;: 제조간접비를 합리적인 배부기준(노동시간, 기계시간 등)에 따라 각 제품에 배부하는 과정이 중요합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;원가계산 방법&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;개별원가계산&lt;/b&gt;: 다품종 소량 생산(조선업, 건설업 등)에 적합하며, 각 작업별로 원가를 집계합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;종합원가계산&lt;/b&gt;: 소품종 대량 생산(정유업, 제지업 등)에 적합하며, 공정별로 원가를 집계하고 &lt;b&gt;완성품 환산량&lt;/b&gt;을 계산하여 기말재공품과 완성품 원가를 구합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;평균법&lt;/b&gt;: 기초재공품 원가와 당기 투입 원가를 구분 없이 평균하여 완성품과 기말재공품 원가를 계산합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;선입선출법&lt;/b&gt;: 기초재공품이 먼저 완성된다고 가정하고, 기초재공품 원가와 당기 투입 원가를 구분하여 원가를 계산합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Ⅲ. 세무회계 (Tax Accounting)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세무회계는 세법 규정에 따라 과세소득과 납부할 세액을 계산하는 절차입니다. 전산세무 2급에서는 &lt;b&gt;부가가치세&lt;/b&gt;와 **소득세(근로소득 중심)**가 핵심입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 부가가치세 (VAT)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;특징&lt;/b&gt;: 국세, 간접세, 일반소비세, 다단계거래세, 소비지국과세원칙, &lt;b&gt;전단계세액공제법&lt;/b&gt; 채택&lt;/li&gt;
&lt;li&gt;&lt;b&gt;과세 요건&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;납세의무자&lt;/b&gt;: 사업자(영리 목적 불문) 및 재화를 수입하는 자&lt;/li&gt;
&lt;li&gt;&lt;b&gt;과세 대상&lt;/b&gt;: 재화 또는 용역의 공급, 재화의 수입&lt;/li&gt;
&lt;li&gt;&lt;b&gt;과세 기간&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반과세자: 1기(1/1~6/30), 2기(7/1~12/31)&lt;/li&gt;
&lt;li&gt;예정신고기간: 1기(1/1~3/31), 2기(7/1~9/30)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;영세율과 면세&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;영세율&lt;/b&gt;: 수출하는 재화 등에 0%의 세율을 적용하여, 매출세액은 없지만 관련 매입세액은 전액 공제받을 수 있습니다 (완전면세).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;면세&lt;/b&gt;: 기초생활필수품, 국민후생용역 등에 적용되며, 매출세액이 없는 대신 관련 매입세액도 공제받지 못합니다 (부분면세).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;매입세액공제&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;공제 가능한 매입세액&lt;/b&gt;: 자기의 사업을 위해 사용되었거나 사용될 재화 또는 용역의 매입세액&lt;/li&gt;
&lt;li&gt;&lt;b&gt;불공제 매입세액&lt;/b&gt;: 사업과 직접 관련 없는 지출, 비영업용 소형승용차 구입&amp;middot;유지 관련 매입세액, 접대비 관련 매입세액, 면세사업 관련 매입세액 등은 공제받을 수 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 소득세 (Income Tax)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;특징&lt;/b&gt;: 개인의 소득을 과세대상으로 하는 국세이며, &lt;b&gt;종합과세&lt;/b&gt;, &lt;b&gt;분류과세&lt;/b&gt;, &lt;b&gt;분리과세&lt;/b&gt; 방식으로 과세합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;종합소득&lt;/b&gt;: &lt;b&gt;이자소득, 배당소득, 사업소득, 근로소득, 연금소득, 기타소득&lt;/b&gt;을 합산하여 과세합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;근로소득&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;총급여액&lt;/b&gt; = 비과세소득을 제외한 연간 근로소득&lt;/li&gt;
&lt;li&gt;&lt;b&gt;근로소득금액&lt;/b&gt; = 총급여액 - 근로소득공제&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;연말정산&lt;/b&gt;: 근로자의 1년간 총급여액에 대한 최종적인 소득세를 계산하고, 매월 원천징수한 세액과 비교하여 차액을 정산하는 절차입니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;소득공제&lt;/b&gt;: 인적공제(기본공제, 추가공제), 연금보험료공제 등&lt;/li&gt;
&lt;li&gt;&lt;b&gt;세액공제&lt;/b&gt;: 근로소득세액공제, 자녀세액공제, 연금계좌세액공제, 보험료&amp;middot;의료비&amp;middot;교육비&amp;middot;기부금 세액공제 등&lt;/li&gt;
&lt;li&gt;각 공제 항목별 요건(나이, 소득금액 등)을 정확히 숙지하는 것이 매우 중요합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Story/경제 Story</category>
      <category>완벽정리</category>
      <category>전산세무2급</category>
      <category>핵심요약</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/685</guid>
      <comments>https://redcow77.tistory.com/685#entry685comment</comments>
      <pubDate>Sat, 12 Jul 2025 22:43:59 +0900</pubDate>
    </item>
    <item>
      <title>전산세무 2급 자격증_3주 계획</title>
      <link>https://redcow77.tistory.com/684</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;전산세무 2급 자격증을 &lt;b&gt;3주(21일)&lt;/b&gt; 동안 준비하려면, 효율적인 &lt;b&gt;이론+실기 병행 전략&lt;/b&gt;이 필요합니다. 특히, 단기간에 준비할 경우 &lt;b&gt;기출문제 반복 학습&lt;/b&gt;과 &lt;b&gt;실습 위주&lt;/b&gt;의 공부가 핵심입니다. 아래는 직장인 기준(평일 1~2시간, 주말 3시간)으로 최적화한 3주 학습 계획입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-07-12 오후 10.30.07.png&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;812&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSErje/btsPgzZA3CY/HeEqlU7Vvy4vTZl5tW53I1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSErje/btsPgzZA3CY/HeEqlU7Vvy4vTZl5tW53I1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSErje/btsPgzZA3CY/HeEqlU7Vvy4vTZl5tW53I1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSErje%2FbtsPgzZA3CY%2FHeEqlU7Vvy4vTZl5tW53I1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;750&quot; height=&quot;438&quot; data-filename=&quot;스크린샷 2025-07-12 오후 10.30.07.png&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;812&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;174&quot; data-start=&quot;153&quot; data-ke-size=&quot;size23&quot;&gt;  1. 회계 이론 핵심 정리&lt;/h3&gt;
&lt;h4 data-end=&quot;193&quot; data-start=&quot;175&quot; data-ke-size=&quot;size20&quot;&gt;✅ 분개 유형별 요약&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;377&quot; data-start=&quot;194&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;233&quot; data-start=&quot;194&quot;&gt;&lt;b&gt;현금 지급&lt;/b&gt;: 현금 &amp;darr; &amp;rarr; 차변에 비용/자산, 대변에 현금&lt;/li&gt;
&lt;li data-end=&quot;267&quot; data-start=&quot;234&quot;&gt;&lt;b&gt;외상매출금 회수&lt;/b&gt;: 차변 현금, 대변 외상매출금&lt;/li&gt;
&lt;li data-end=&quot;302&quot; data-start=&quot;268&quot;&gt;&lt;b&gt;감가상각&lt;/b&gt;: 차변 감가상각비, 대변 감가상각누계액&lt;/li&gt;
&lt;li data-end=&quot;377&quot; data-start=&quot;303&quot;&gt;&lt;b&gt;부가세 대급금/예수금 처리&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;377&quot; data-start=&quot;328&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;351&quot; data-start=&quot;328&quot;&gt;매출시: 대변 매출 + 부가세예수금&lt;/li&gt;
&lt;li data-end=&quot;377&quot; data-start=&quot;354&quot;&gt;매입시: 차변 매입 + 부가세대급금&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;395&quot; data-start=&quot;379&quot; data-ke-size=&quot;size20&quot;&gt;✅ 계정과목 구분&lt;/h4&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 53px;&quot; border=&quot;1&quot; data-end=&quot;513&quot; data-start=&quot;396&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;자산&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;부채&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;자본&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;수익&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;비용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;513&quot; data-start=&quot;460&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;476&quot; data-start=&quot;460&quot;&gt;현금, 외상매출금, 비품&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-end=&quot;489&quot; data-start=&quot;476&quot; data-col-size=&quot;sm&quot;&gt;외상매입금, 선수금&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-end=&quot;495&quot; data-start=&quot;489&quot; data-col-size=&quot;sm&quot;&gt;자본금&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-end=&quot;500&quot; data-start=&quot;495&quot; data-col-size=&quot;sm&quot;&gt;매출&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-end=&quot;513&quot; data-start=&quot;500&quot; data-col-size=&quot;sm&quot;&gt;급여, 감가상각비&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;537&quot; data-start=&quot;520&quot; data-ke-size=&quot;size23&quot;&gt;  2. 세무회계 요약&lt;/h3&gt;
&lt;h4 data-end=&quot;553&quot; data-start=&quot;538&quot; data-ke-size=&quot;size20&quot;&gt;✅ 부가가치세 핵심&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;626&quot; data-start=&quot;554&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;581&quot; data-start=&quot;554&quot;&gt;과세기간: 1기(12월)&lt;/li&gt;
&lt;li data-end=&quot;601&quot; data-start=&quot;582&quot;&gt;&lt;b&gt;세금계산서 발급일자 기준&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;626&quot; data-start=&quot;602&quot;&gt;납부세액 = &lt;b&gt;매출세액 - 매입세액&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;639&quot; data-start=&quot;628&quot; data-ke-size=&quot;size20&quot;&gt;✅ 원천징수&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;715&quot; data-start=&quot;640&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;666&quot; data-start=&quot;640&quot;&gt;&lt;b&gt;근로소득&lt;/b&gt;: 월급여 x 세율표 적용&lt;/li&gt;
&lt;li data-end=&quot;715&quot; data-start=&quot;667&quot;&gt;&lt;b&gt;사업소득&lt;/b&gt;: 지급액의 3.3% 원천징수 (소득세 3% + 지방소득세 0.3%)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;730&quot; data-start=&quot;717&quot; data-ke-size=&quot;size20&quot;&gt;✅ 소득세 신고&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;768&quot; data-start=&quot;731&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;744&quot; data-start=&quot;731&quot;&gt;5월 종합소득세 신고&lt;/li&gt;
&lt;li data-end=&quot;768&quot; data-start=&quot;745&quot;&gt;필요경비 제외한 금액에 대해 세율 적용&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Story/경제 Story</category>
      <category>3주계획</category>
      <category>전산세무2급</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/684</guid>
      <comments>https://redcow77.tistory.com/684#entry684comment</comments>
      <pubDate>Sat, 12 Jul 2025 22:38:43 +0900</pubDate>
    </item>
    <item>
      <title>amCharts 4 라이브러리  pieChart</title>
      <link>https://redcow77.tistory.com/683</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Gemini_Generated_Image_srxevksrxevksrxe.png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d6Qna7/btsPcRNyrev/OizLKdKU6JoLVgDwapOVak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d6Qna7/btsPcRNyrev/OizLKdKU6JoLVgDwapOVak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d6Qna7/btsPcRNyrev/OizLKdKU6JoLVgDwapOVak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd6Qna7%2FbtsPcRNyrev%2FOizLKdKU6JoLVgDwapOVak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;500&quot; data-filename=&quot;Gemini_Generated_Image_srxevksrxevksrxe.png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, amCharts 4 라이브러리가 설치되어 있는지 확인해주세요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm install @amcharts/amcharts4&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm install @amcharts/amcharts4/charts&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm install @amcharts/amcharts4/themes&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1752158211912&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useLayoutEffect, useRef } from 'react';
import * as am4core from &quot;@amcharts/amcharts4/core&quot;;
import * as am4charts from &quot;@amcharts/amcharts4/charts&quot;;
import am4themes_animated from &quot;@amcharts/amcharts4/themes/animated&quot;;

// amCharts 폰트 또는 다른 글로벌 설정이 필요할 수 있습니다.
// am4core.options.autoSetClassName = true; // 클래스 이름 자동 설정 (선택 사항)

function Am4PieChart({ data }) {
  const chartRef = useRef(null);

  const effectiveData = data || [
    { value: 60, category: &quot;Pass&quot;, count: 5 },
    { value: 40.0, category: &quot;Fail&quot;, count: 9 },
  ];

  useLayoutEffect(() =&amp;gt; {
    // 테마 등록 (항상 차트 생성 전에 등록)
    am4core.useTheme(am4themes_animated);

    // 1. 차트 인스턴스 생성
    // &quot;am4chartdiv&quot;는 차트를 렌더링할 HTML div 요소의 ID입니다.
    let chart = am4core.create(&quot;am4chartdiv&quot;, am4charts.PieChart);
    chartRef.current = chart; // 차트 인스턴스 저장

    // 2. 데이터 설정
    chart.data = effectiveData;

    // 3. 파이 시리즈 생성
    let pieSeries = chart.series.push(new am4charts.PieSeries());
    pieSeries.dataFields.value = &quot;value&quot;;
    pieSeries.dataFields.category = &quot;category&quot;;

    // 라벨 설정
    pieSeries.labels.template.adapter.add(&quot;text&quot;, function(text, target) {
      // {category}: {value.percent.formatNumber('#.#')}%, {count}ea 형식
      let dataItem = target.dataItem;
      let category = dataItem.category;
      let percentage = am4core.number.format(dataItem.value / chart.data.reduce((sum, item) =&amp;gt; sum + item.value, 0) * 100, &quot;#.#&quot;);
      let count = dataItem.dataContext.count;
      return `${category}: ${percentage}%, ${count}ea`;
    });

    // 라벨 위치 및 스타일 설정
    pieSeries.labels.template.radius = -40; // 슬라이스 중앙에서 안쪽으로 위치 조정
    pieSeries.labels.template.fill = am4core.color(&quot;#FFFFFF&quot;); // 흰색 텍스트
    pieSeries.labels.template.strokeOpacity = 0; // 라벨 테두리 제거 (기본값일 수 있음)
    pieSeries.labels.template.horizontalCenter = &quot;middle&quot;;
    pieSeries.labels.template.verticalCenter = &quot;middle&quot;;
    pieSeries.labels.template.rotation = 0; // 라벨 텍스트 회전 비활성화

    // 라벨 배경 (사각형 형태)
    pieSeries.labels.template.background = new am4core.Rectangle();
    pieSeries.labels.template.background.fill = am4core.color(&quot;#000000&quot;); // 검정색 배경
    pieSeries.labels.template.background.fillOpacity = 0.3; // 투명도
    pieSeries.labels.template.background.cornerRadius(3, 3, 3, 3); // 둥근 모서리
    pieSeries.labels.template.background.padding(4, 8, 4, 8); // 패딩

    // 라벨 선 제거 (amCharts 4에서는 `ticks`를 제어)
    pieSeries.ticks.template.disabled = true; // 틱(라인) 비활성화
    pieSeries.alignLabels = false; // 라벨이 슬라이스 내부에 정렬되도록 (겹칠 수 있음)

    // 슬라이스 설정
    pieSeries.slices.template.stroke = am4core.color(&quot;#fff&quot;); // 슬라이스 테두리
    pieSeries.slices.template.strokeWidth = 1;
    pieSeries.slices.template.strokeOpacity = 1;

    // 호버 효과 비활성화 (툴팁 제거 및 상태 변경 비활성화)
    pieSeries.slices.template.tooltipText = &quot;&quot;; // 툴팁 텍스트를 비워 툴팁이 나타나지 않게 함
    pieSeries.slices.template.states.getKey(&quot;hover&quot;).properties.scale = 1; // 호버 시 확대 비활성화
    pieSeries.slices.template.states.getKey(&quot;active&quot;).properties.shiftRadius = 0; // 클릭 시 벗어나는 효과 비활성화

    // 슬라이스 색상 설정 (Pass/Fail에 따라 다르게)
    pieSeries.colors.list = [
      am4core.color(&quot;#67B7DC&quot;), // Pass 색상 (첫 번째 데이터 아이템)
      am4core.color(&quot;#FF6347&quot;)  // Fail 색상 (두 번째 데이터 아이템)
      // 데이터가 더 많다면 다른 색상을 추가하거나 adapter를 사용할 수 있습니다.
    ];
    // 또는 adapter를 사용하여 동적으로 색상 지정 (더 유연함)
    // pieSeries.slices.template.adapter.add(&quot;fill&quot;, function(fill, target) {
    //   if (target.dataItem.category === &quot;Pass&quot;) {
    //     return am4core.color(&quot;#67B7DC&quot;);
    //   } else if (target.dataItem.category === &quot;Fail&quot;) {
    //     return am4core.color(&quot;#FF6347&quot;);
    //   }
    //   return fill;
    // });


    // 4. 레전드 (범례) 추가 (선택 사항)
    chart.legend = new am4charts.Legend();
    chart.legend.position = &quot;bottom&quot;;

    // cleanup 함수
    return () =&amp;gt; {
      if (chartRef.current) {
        chartRef.current.dispose();
      }
    };
  }, [effectiveData]);

  return (
    &amp;lt;div id=&quot;am4chartdiv&quot; style={{ width: &quot;100%&quot;, height: &quot;500px&quot; }}&amp;gt;&amp;lt;/div&amp;gt;
  );
}

export default Am4PieChart;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>amcharts</category>
      <category>piechart</category>
      <category>react</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/683</guid>
      <comments>https://redcow77.tistory.com/683#entry683comment</comments>
      <pubDate>Thu, 10 Jul 2025 23:40:43 +0900</pubDate>
    </item>
    <item>
      <title>요즘 뜨는 'Agent AI', 도대체 뭘까?</title>
      <link>https://redcow77.tistory.com/682</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근 AI 업계에서 가장 핫한 키워드를 꼽으라면 단연 &lt;b&gt;Agent AI&lt;/b&gt;가 빠지지 않습니다. ChatGPT, Claude, Gemini 같은 대형 언어 모델(LLM)이 주목받은 데 이어, 이제는 단순히 &quot;똑똑한 채팅&quot;을 넘어 &lt;b&gt;스스로 목표를 설정하고 실행하는 인공지능&lt;/b&gt;이 각광받고 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;374&quot; data-start=&quot;329&quot; data-ke-size=&quot;size16&quot;&gt;Agent AI에 대해 쉽게 설명하는 글을 찾아보았습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-end=&quot;374&quot; data-start=&quot;329&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;394&quot; data-start=&quot;381&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Agent AI란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;566&quot; data-start=&quot;396&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Agent AI&lt;/b&gt;는 간단히 말해 &lt;b&gt;스스로 판단하고 행동할 수 있는 인공지능&lt;/b&gt;입니다. 기존 AI가 질문에 답하거나 주어진 명령을 처리하는 데 그쳤다면, Agent AI는 더 나아가 &lt;b&gt;&quot;내가 지금 뭘 해야 하지?&quot;를 스스로 생각&lt;/b&gt;하고, 목표를 달성하기 위한 계획을 세워 실행까지 할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;621&quot; data-start=&quot;568&quot; data-ke-size=&quot;size16&quot;&gt;즉, 사람이 일일이 시키지 않아도 &lt;b&gt;상황을 인식하고 알아서 움직이는 AI&lt;/b&gt;라고 할 수 있습니다 .&lt;/p&gt;
&lt;p data-end=&quot;621&quot; data-start=&quot;568&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-end=&quot;621&quot; data-start=&quot;568&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;653&quot; data-start=&quot;641&quot; data-ke-size=&quot;size23&quot;&gt;  기존 AI&lt;/h3&gt;
&lt;blockquote data-end=&quot;691&quot; data-start=&quot;654&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;691&quot; data-start=&quot;656&quot; data-ke-size=&quot;size16&quot;&gt;&quot;이메일 제목을 요약해줘.&quot;&lt;br /&gt;&amp;rarr; AI가 간단한 요약 제공&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-end=&quot;708&quot; data-start=&quot;693&quot; data-ke-size=&quot;size23&quot;&gt;  Agent AI&lt;/h3&gt;
&lt;blockquote data-end=&quot;868&quot; data-start=&quot;709&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;765&quot; data-start=&quot;711&quot; data-ke-size=&quot;size16&quot;&gt;&quot;고객 불만 관련 메일을 정리하고, 요약해서 보고서를 작성해줘.&quot;&lt;br /&gt;&amp;rarr; Agent AI는&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;868&quot; data-start=&quot;768&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;782&quot; data-start=&quot;768&quot;&gt;이메일을 분류하고&lt;/li&gt;
&lt;li data-end=&quot;803&quot; data-start=&quot;785&quot;&gt;관련 정보를 추출한 다음&lt;/li&gt;
&lt;li data-end=&quot;819&quot; data-start=&quot;806&quot;&gt;문서로 요약하고&lt;/li&gt;
&lt;li data-end=&quot;868&quot; data-start=&quot;822&quot;&gt;심지어 Google Docs에 저장하거나 상사에게 메일로 보낼 수도 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;907&quot; data-start=&quot;870&quot; data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;복잡한 일련의 작업을 스스로 분해하고 실행&lt;/b&gt;하는것을 Agent AI 라고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;907&quot; data-start=&quot;870&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-end=&quot;927&quot; data-start=&quot;914&quot; data-ke-size=&quot;size26&quot;&gt;Agent AI는 어떻게 동작을 할까?&lt;/h2&gt;
&lt;p data-end=&quot;959&quot; data-start=&quot;929&quot; data-ke-size=&quot;size16&quot;&gt;Agent AI는 보통 다음 3가지 요소로 구성됩니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1095&quot; data-start=&quot;961&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;995&quot; data-start=&quot;961&quot;&gt;&lt;b&gt;목표 (Goal)&lt;/b&gt; &amp;ndash; 예: &quot;오늘 뉴스 요약하기&quot;&lt;/li&gt;
&lt;li data-end=&quot;1041&quot; data-start=&quot;996&quot;&gt;&lt;b&gt;행동(Action) 수단&lt;/b&gt; &amp;ndash; 예: 웹 검색, 요약하기, 파일 저장 등&lt;/li&gt;
&lt;li data-end=&quot;1095&quot; data-start=&quot;1042&quot;&gt;&lt;b&gt;계획(Planning) 능력&lt;/b&gt; &amp;ndash; 어떤 순서로 어떤 도구를 써서 목표를 달성할지 판단&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;1150&quot; data-start=&quot;1097&quot; data-ke-size=&quot;size16&quot;&gt;이러한 구조를 바탕으로 Agent AI는 &quot;도구 사용 능력을 갖춘 똑똑한 비서&quot;처럼 움직입니다.&lt;/p&gt;
&lt;p data-end=&quot;1150&quot; data-start=&quot;1097&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-end=&quot;1392&quot; data-start=&quot;1373&quot; data-ke-size=&quot;size26&quot;&gt;대표적인 Agent AI&amp;nbsp;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-06-08 오전 4.59.22.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;1332&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgwIu4/btsOrqp5Zyu/Tkl1w5RyK4uQkWxC6cmwWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgwIu4/btsOrqp5Zyu/Tkl1w5RyK4uQkWxC6cmwWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgwIu4/btsOrqp5Zyu/Tkl1w5RyK4uQkWxC6cmwWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgwIu4%2FbtsOrqp5Zyu%2FTkl1w5RyK4uQkWxC6cmwWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;1332&quot; data-filename=&quot;스크린샷 2025-06-08 오전 4.59.22.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;1332&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-end=&quot;1561&quot; data-start=&quot;1550&quot; data-ke-size=&quot;size26&quot;&gt;현재 사용성과 미래의 가능성&lt;/h2&gt;
&lt;p data-end=&quot;1651&quot; data-start=&quot;1563&quot; data-ke-size=&quot;size16&quot;&gt;Agent AI는 다음과 같은 분야에서 활용되고 있어요.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1366&quot; data-start=&quot;1211&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1256&quot; data-start=&quot;1211&quot;&gt;  &lt;b&gt;자동 웹 리서치&lt;/b&gt;: 예) 여러 뉴스 사이트를 읽고 한 문장으로 요약&lt;/li&gt;
&lt;li data-end=&quot;1298&quot; data-start=&quot;1257&quot;&gt;  &lt;b&gt;쇼핑 비교 및 추천&lt;/b&gt;: 예) &quot;가성비 좋은 노트북 추천해줘&quot;&lt;/li&gt;
&lt;li data-end=&quot;1325&quot; data-start=&quot;1299&quot;&gt;  &lt;b&gt;일정 조율 및 자동 이메일 작성&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1366&quot; data-start=&quot;1326&quot;&gt;  &lt;b&gt;회사 업무 자동화&lt;/b&gt;: 리포트 작성, 데이터 분석, 정리 등&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1651&quot; data-start=&quot;1563&quot; data-ke-size=&quot;size16&quot;&gt;Agent AI는 단순한 자동화 그 이상입니다. 우리가 일일이 처리해야 했던 복잡했던 디지털 작업들을 대신해주는 '디지털 동료'가 되어줄 가능성이 큽니다.&lt;/p&gt;
&lt;p data-end=&quot;1715&quot; data-start=&quot;1653&quot; data-ke-size=&quot;size16&quot;&gt;하지만 동시에, &lt;b&gt;어디까지 자동화할 것인가&lt;/b&gt;, &lt;b&gt;책임은 누구에게 있는가&lt;/b&gt; 등의 윤리적 고민도 필요합니다.&lt;/p&gt;</description>
      <category>프로그래밍/Etc</category>
      <category>agentai</category>
      <category>AI</category>
      <category>ChatGPT</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/682</guid>
      <comments>https://redcow77.tistory.com/682#entry682comment</comments>
      <pubDate>Sun, 8 Jun 2025 05:11:29 +0900</pubDate>
    </item>
    <item>
      <title>  React Saga 완벽 정리: 복잡한 비동기 로직을 간결하게!</title>
      <link>https://redcow77.tistory.com/681</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-29 오후 8.55.45.png&quot; data-origin-width=&quot;1220&quot; data-origin-height=&quot;814&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciZ1Th/btsOi8PvfAH/V97b6QcAKxgPlb3MbOkiP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciZ1Th/btsOi8PvfAH/V97b6QcAKxgPlb3MbOkiP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciZ1Th/btsOi8PvfAH/V97b6QcAKxgPlb3MbOkiP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciZ1Th%2FbtsOi8PvfAH%2FV97b6QcAKxgPlb3MbOkiP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;334&quot; data-filename=&quot;스크린샷 2025-05-29 오후 8.55.45.png&quot; data-origin-width=&quot;1220&quot; data-origin-height=&quot;814&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redux를 사용할 때, 비동기 작업(API 호출, 웹소켓 등)을 깔끔하게 처리하고 싶으신가요?&lt;br /&gt;&lt;b&gt;React Saga&lt;/b&gt;는 바로 그런 고민을 해결해주는 &lt;b&gt;미들웨어 라이브러리&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React Saga는 &lt;b&gt;복잡한 비동기 흐름을 선언적으로 표현하고, 유지보수성과 테스트 용이성&lt;/b&gt;을 높여주는 강력한 도구입니다.&lt;/p&gt;
&lt;hr data-end=&quot;251&quot; data-start=&quot;248&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;268&quot; data-start=&quot;253&quot; data-ke-size=&quot;size26&quot;&gt;  사이드 이펙트란?&lt;/h2&gt;
&lt;blockquote data-end=&quot;331&quot; data-start=&quot;270&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;331&quot; data-start=&quot;272&quot; data-ke-size=&quot;size16&quot;&gt;**사이드 이펙트(side effects)**란 애플리케이션의 주 흐름 외부에서 발생하는 작업을 말합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;422&quot; data-start=&quot;333&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;341&quot; data-start=&quot;333&quot;&gt;API 호출&lt;/li&gt;
&lt;li data-end=&quot;354&quot; data-start=&quot;342&quot;&gt;브라우저 캐시 접근&lt;/li&gt;
&lt;li data-end=&quot;422&quot; data-start=&quot;355&quot;&gt;웹소켓 통신&lt;br /&gt;등이 이에 해당되며, 이런 작업은 Redux의 순수한 액션/리듀서 구조에서는 직접 다루기 어렵습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;427&quot; data-start=&quot;424&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;447&quot; data-start=&quot;429&quot; data-ke-size=&quot;size26&quot;&gt;  React Saga란?&lt;/h2&gt;
&lt;p data-end=&quot;573&quot; data-start=&quot;449&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;React Saga&lt;/b&gt;는 Redux 애플리케이션에서 사이드 이펙트를 관리하기 위한 &lt;b&gt;미들웨어&lt;/b&gt;입니다.&lt;br /&gt;**ES6 제너레이터(Generator)**를 활용하여 비동기 흐름을 마치 동기처럼 작성할 수 있게 해줍니다.&lt;/p&gt;
&lt;h3 data-end=&quot;595&quot; data-start=&quot;575&quot; data-ke-size=&quot;size23&quot;&gt;✅ React Saga의 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;806&quot; data-start=&quot;597&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;662&quot; data-start=&quot;597&quot;&gt;&lt;b&gt;복잡한 비동기 흐름 처리&lt;/b&gt;&lt;br /&gt;여러 API 호출, 조건 분기, 병렬 실행 등 복잡한 로직을 깔끔하게 관리&lt;/li&gt;
&lt;li data-end=&quot;713&quot; data-start=&quot;664&quot;&gt;&lt;b&gt;테스트 용이성&lt;/b&gt;&lt;br /&gt;제너레이터 함수 + 이펙트 객체로 로직을 테스트하기 쉬움&lt;/li&gt;
&lt;li data-end=&quot;757&quot; data-start=&quot;715&quot;&gt;&lt;b&gt;관심사 분리&lt;/b&gt;&lt;br /&gt;비동기 로직을 컴포넌트나 액션 생성자에서 분리&lt;/li&gt;
&lt;li data-end=&quot;806&quot; data-start=&quot;759&quot;&gt;&lt;b&gt;선언적 프로그래밍&lt;/b&gt;&lt;br /&gt;yield를 통해 코드 의도가 명확하게 드러남&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;824&quot; data-start=&quot;813&quot; data-ke-size=&quot;size26&quot;&gt;⚙️ 주요 개념&lt;/h2&gt;
&lt;h3 data-end=&quot;844&quot; data-start=&quot;826&quot; data-ke-size=&quot;size23&quot;&gt;1.   사가(Saga)&lt;/h3&gt;
&lt;blockquote data-end=&quot;877&quot; data-start=&quot;846&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;877&quot; data-start=&quot;848&quot; data-ke-size=&quot;size16&quot;&gt;비동기 작업을 처리하는 &lt;b&gt;제너레이터 함수&lt;/b&gt;입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;923&quot; data-start=&quot;879&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;903&quot; data-start=&quot;879&quot;&gt;특정 액션을 감시하고 &amp;rarr; 해당 작업 수행&lt;/li&gt;
&lt;li data-end=&quot;923&quot; data-start=&quot;904&quot;&gt;function* 문법 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;928&quot; data-start=&quot;925&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;951&quot; data-start=&quot;930&quot; data-ke-size=&quot;size23&quot;&gt;2. ⚡ 이펙트(Effects)&lt;/h3&gt;
&lt;blockquote data-end=&quot;993&quot; data-start=&quot;953&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;993&quot; data-start=&quot;955&quot; data-ke-size=&quot;size16&quot;&gt;사가가 미들웨어에게 &quot;무엇을 할지&quot; 명령하는 &lt;b&gt;순수 객체&lt;/b&gt;입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1034&quot; data-start=&quot;995&quot; data-ke-size=&quot;size16&quot;&gt;주요 이펙트 함수들 (from redux-saga/effects):&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;이펙트 함수설명
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1424&quot; data-start=&quot;1036&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1424&quot; data-start=&quot;1074&quot;&gt;
&lt;tr data-end=&quot;1102&quot; data-start=&quot;1074&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1090&quot; data-start=&quot;1074&quot;&gt;put(action)&lt;/td&gt;
&lt;td data-end=&quot;1102&quot; data-start=&quot;1090&quot; data-col-size=&quot;sm&quot;&gt;액션을 디스패치&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1153&quot; data-start=&quot;1103&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1125&quot; data-start=&quot;1103&quot;&gt;call(fn, ...args)&lt;/td&gt;
&lt;td data-end=&quot;1153&quot; data-start=&quot;1125&quot; data-col-size=&quot;sm&quot;&gt;함수를 호출하고 Promise 완료를 기다림&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1193&quot; data-start=&quot;1154&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1172&quot; data-start=&quot;1154&quot;&gt;take(pattern)&lt;/td&gt;
&lt;td data-end=&quot;1193&quot; data-start=&quot;1172&quot; data-col-size=&quot;sm&quot;&gt;특정 액션이 발생할 때까지 대기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1245&quot; data-start=&quot;1194&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1223&quot; data-start=&quot;1194&quot;&gt;takeEvery(pattern, saga)&lt;/td&gt;
&lt;td data-end=&quot;1245&quot; data-start=&quot;1223&quot; data-col-size=&quot;sm&quot;&gt;액션마다 사가 실행 (병렬 처리)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1305&quot; data-start=&quot;1246&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1276&quot; data-start=&quot;1246&quot;&gt;takeLatest(pattern, saga)&lt;/td&gt;
&lt;td data-end=&quot;1305&quot; data-start=&quot;1276&quot; data-col-size=&quot;sm&quot;&gt;가장 마지막 액션만 처리 (이전 사가는 취소)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1346&quot; data-start=&quot;1306&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1327&quot; data-start=&quot;1306&quot;&gt;select(selector)&lt;/td&gt;
&lt;td data-end=&quot;1346&quot; data-start=&quot;1327&quot; data-col-size=&quot;sm&quot;&gt;Redux 스토어 상태 접근&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1384&quot; data-start=&quot;1347&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1360&quot; data-start=&quot;1347&quot;&gt;fork(fn)&lt;/td&gt;
&lt;td data-end=&quot;1384&quot; data-start=&quot;1360&quot; data-col-size=&quot;sm&quot;&gt;비동기 작업을 병렬로 백그라운드 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1424&quot; data-start=&quot;1385&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1407&quot; data-start=&quot;1385&quot;&gt;all([...effects])&lt;/td&gt;
&lt;td data-end=&quot;1424&quot; data-start=&quot;1407&quot; data-col-size=&quot;sm&quot;&gt;여러 이펙트를 병렬 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1429&quot; data-start=&quot;1426&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1454&quot; data-start=&quot;1431&quot; data-ke-size=&quot;size23&quot;&gt;3. 와처 사가 &amp;amp; 워커 사가&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1583&quot; data-start=&quot;1456&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1524&quot; data-start=&quot;1456&quot;&gt;&lt;b&gt;와처 사가 (Watcher Saga)&lt;/b&gt;&lt;br /&gt;takeEvery, takeLatest 등을 통해 액션 감시&lt;/li&gt;
&lt;li data-end=&quot;1583&quot; data-start=&quot;1526&quot;&gt;&lt;b&gt;워커 사가 (Worker Saga)&lt;/b&gt;&lt;br /&gt;실제 비동기 작업을 수행하고, 결과 액션 디스패치&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1588&quot; data-start=&quot;1585&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1614&quot; data-start=&quot;1590&quot; data-ke-size=&quot;size26&quot;&gt;  흐름 예시: 사용자 정보 가져오기&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1748519991124&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[1] 컴포넌트에서 action dispatch (FETCH_USER_REQUEST)
      &amp;darr;
[2] 와처 saga가 감지 (takeLatest 사용)
      &amp;darr;
[3] 워커 saga 실행 &amp;rarr; API 호출 (call)
      &amp;darr;
[4] 성공 시 FETCH_USER_SUCCESS, 실패 시 FETCH_USER_FAILURE 디스패치 (put)
      &amp;darr;
[5] Reducer가 상태 업데이트
      &amp;darr;
[6] 컴포넌트가 변경된 상태를 반영해 리렌더링&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1884&quot; data-start=&quot;1881&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2639&quot; data-start=&quot;2614&quot; data-ke-size=&quot;size26&quot;&gt;✅ 언제 React Saga를 사용할까?&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2801&quot; data-start=&quot;2641&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2676&quot; data-start=&quot;2641&quot;&gt;복잡한 &lt;b&gt;비동기 로직&lt;/b&gt;, &lt;b&gt;동시성 제어&lt;/b&gt;가 필요할 때&lt;/li&gt;
&lt;li data-end=&quot;2727&quot; data-start=&quot;2677&quot;&gt;API 호출, 소켓 관리 등 다양한 사이드 이펙트를 &lt;b&gt;체계적으로 관리&lt;/b&gt;하고 싶을 때&lt;/li&gt;
&lt;li data-end=&quot;2758&quot; data-start=&quot;2728&quot;&gt;&lt;b&gt;비동기 로직의 테스트&lt;/b&gt;가 중요한 프로젝트일 때&lt;/li&gt;
&lt;li data-end=&quot;2801&quot; data-start=&quot;2759&quot;&gt;컴포넌트와 로직을 &lt;b&gt;명확히 분리&lt;/b&gt;해 코드 유지보수성을 높이고 싶을 때&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-end=&quot;2882&quot; data-start=&quot;2803&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2882&quot; data-start=&quot;2805&quot; data-ke-size=&quot;size16&quot;&gt;⚠️ 단순한 비동기 처리라면 redux-thunk도 충분합니다. 하지만 프로젝트가 커질수록 React Saga의 장점이 빛을 발합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;1884&quot; data-start=&quot;1881&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1898&quot; data-start=&quot;1886&quot; data-ke-size=&quot;size26&quot;&gt; ️ 사용 방법&lt;/h2&gt;
&lt;h3 data-end=&quot;1996&quot; data-start=&quot;1977&quot; data-ke-size=&quot;size23&quot;&gt;1. 스토어에 미들웨어 적용&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1748520097397&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// store.js
import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from './reducers';
import rootSaga from './sagas';

const sagaMiddleware = createSagaMiddleware();

const store = createStore(
  rootReducer,
  applyMiddleware(sagaMiddleware)
);

sagaMiddleware.run(rootSaga);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;2354&quot; data-start=&quot;2351&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2371&quot; data-start=&quot;2356&quot; data-ke-size=&quot;size23&quot;&gt;2. 루트 사가 정의&lt;/h3&gt;
&lt;pre id=&quot;code_1748520118006&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// sagas/index.js
import { all } from 'redux-saga/effects';
import { watchFetchUserRequest } from './userSagas';

export default function* rootSaga() {
  yield all([
    watchFetchUserRequest(),
    // 다른 와처 사가 추가 가능
  ]);
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>react saga</category>
      <category>react.js</category>
      <category>react비동기처리</category>
      <category>Redux</category>
      <category>SAGA</category>
      <category>리액트</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/681</guid>
      <comments>https://redcow77.tistory.com/681#entry681comment</comments>
      <pubDate>Thu, 29 May 2025 21:04:13 +0900</pubDate>
    </item>
    <item>
      <title>ag-Grid-React  Excel 다운로드</title>
      <link>https://redcow77.tistory.com/679</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img.png&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;744&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpjmXW/btsN6wjszfU/KZXN7qsolWNGkjKwAaHzbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpjmXW/btsN6wjszfU/KZXN7qsolWNGkjKwAaHzbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpjmXW/btsN6wjszfU/KZXN7qsolWNGkjKwAaHzbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpjmXW%2FbtsN6wjszfU%2FKZXN7qsolWNGkjKwAaHzbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;347&quot; data-filename=&quot;img.png&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;744&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ag-grid-react에서 &lt;b&gt;엑셀 다운로드(Excel Export)&lt;/b&gt; 기능은 매우 강력하며, &lt;b&gt;Enterprise 기능이 아닌 Community Edition에서도 사용&lt;/b&gt; 가능합니다. 단순 클릭으로 현재 그리드에 표시된 데이터를 .xlsx 또는 .csv 형식으로 내보낼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;1445&quot; data-end=&quot;1462&quot; data-ke-size=&quot;size26&quot;&gt;✅ 1. Excel 파일 다운로드 (XLSX)&lt;/h2&gt;
&lt;pre id=&quot;code_1747831790672&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useRef, useState } from &quot;react&quot;;
import { AgGridReact } from &quot;ag-grid-react&quot;;
import &quot;ag-grid-community/styles/ag-grid.css&quot;;
import &quot;ag-grid-community/styles/ag-theme-alpine.css&quot;;

const GridExportExcel = () =&amp;gt; {
  const gridRef = useRef();

  const [rowData] = useState([
    { make: &quot;Hyundai&quot;, model: &quot;Sonata&quot;, price: 2500 },
    { make: &quot;Kia&quot;, model: &quot;K5&quot;, price: 2700 },
  ]);

  const [columnDefs] = useState([
    { field: &quot;make&quot; },
    { field: &quot;model&quot; },
    { field: &quot;price&quot; },
  ]);

  const handleExportExcel = () =&amp;gt; {
    gridRef.current.api.exportDataAsExcel();
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;button onClick={handleExportExcel}&amp;gt;Excel Export&amp;lt;/button&amp;gt;
      &amp;lt;div className=&quot;ag-theme-alpine&quot; style={{ height: 400, width: 600 }}&amp;gt;
        &amp;lt;AgGridReact
          ref={gridRef}
          rowData={rowData}
          columnDefs={columnDefs}
        /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default GridExportExcel;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1160&quot; data-start=&quot;1146&quot; data-ke-size=&quot;size26&quot;&gt;  exportDataAsExcel 옵션&lt;/h2&gt;
&lt;p data-end=&quot;1198&quot; data-start=&quot;1162&quot; data-ke-size=&quot;size16&quot;&gt;exportDataAsExcel()에 옵션을 줄 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1747831873978&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gridRef.current.api.exportDataAsExcel({
  fileName: &quot;my-data.xlsx&quot;,
  sheetName: &quot;Sheet1&quot;,
  columnKeys: [&quot;make&quot;, &quot;model&quot;], // 특정 컬럼만
  allColumns: true,              // 숨겨진 컬럼까지 포함
  onlySelected: false,           // 선택된 행만
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1462&quot; data-start=&quot;1445&quot; data-ke-size=&quot;size26&quot;&gt;✅ 2. CSV 파일 다운로드&lt;/h2&gt;
&lt;p data-end=&quot;1492&quot; data-start=&quot;1464&quot; data-ke-size=&quot;size16&quot;&gt;엑셀보다 더 가볍게 CSV로도 내보낼 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1747831990473&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gridRef.current.api.exportDataAsCsv({
  fileName: &quot;my-data.csv&quot;,
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자주 사용하는 옵션 들로 형식(예: 날짜 포맷 변경, 숫자 통화 처리, 특정 컬럼 제외 등)에 맞춰 &lt;b&gt;엑셀 포맷을 커스터마이징&lt;/b&gt;할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-21 오후 9.54.03.png&quot; data-origin-width=&quot;1578&quot; data-origin-height=&quot;862&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccYOZp/btsN6mVQcy1/0hnL68Q3g0EkBkJYkd6btk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccYOZp/btsN6mVQcy1/0hnL68Q3g0EkBkJYkd6btk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccYOZp/btsN6mVQcy1/0hnL68Q3g0EkBkJYkd6btk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccYOZp%2FbtsN6mVQcy1%2F0hnL68Q3g0EkBkJYkd6btk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;382&quot; data-filename=&quot;스크린샷 2025-05-21 오후 9.54.03.png&quot; data-origin-width=&quot;1578&quot; data-origin-height=&quot;862&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>aggridreact</category>
      <category>exportexcel</category>
      <category>react</category>
      <category>엑셀다운로드</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/679</guid>
      <comments>https://redcow77.tistory.com/679#entry679comment</comments>
      <pubDate>Wed, 21 May 2025 21:56:09 +0900</pubDate>
    </item>
    <item>
      <title>ag-Grid-React  Row 편집</title>
      <link>https://redcow77.tistory.com/678</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-17 오전 8.06.00.png&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;744&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qfIPk/btsN2MyFkLw/fu6bM3H9N96OODBwdNjyJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qfIPk/btsN2MyFkLw/fu6bM3H9N96OODBwdNjyJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qfIPk/btsN2MyFkLw/fu6bM3H9N96OODBwdNjyJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqfIPk%2FbtsN2MyFkLw%2Ffu6bM3H9N96OODBwdNjyJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;347&quot; data-filename=&quot;스크린샷 2025-05-17 오전 8.06.00.png&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;744&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ag-grid-react에서 &lt;b&gt;행(row) 편집&lt;/b&gt; 기능은 매우 강력하며, 인라인(in-place) 방식으로 데이터를 편집할 수 있습니다. React 개발자의 관점에서 보면, 셀 편집은 자동으로 관리되지만, 외부 상태 동기화나 저장 버튼과의 연동을 직접 제어할 수 있어야 실전에서 유용합니다.&lt;/p&gt;
&lt;hr data-end=&quot;171&quot; data-start=&quot;168&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;188&quot; data-start=&quot;173&quot; data-ke-size=&quot;size26&quot;&gt;✅ 기본 행 편집 방식&lt;/h2&gt;
&lt;p data-end=&quot;277&quot; data-start=&quot;190&quot; data-ke-size=&quot;size16&quot;&gt;Ag-Grid는 &lt;b&gt;셀 단위 편집&lt;/b&gt;을 지원하지만, 그리드 옵션을 조금만 설정하면 **행 단위 편집(row editing)**처럼 동작하게 할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;277&quot; data-start=&quot;190&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1747520694636&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useState } from &quot;react&quot;;
import { AgGridReact } from &quot;ag-grid-react&quot;;
import &quot;ag-grid-community/styles/ag-grid.css&quot;;
import &quot;ag-grid-community/styles/ag-theme-alpine.css&quot;;

const RowDataEidt = () =&amp;gt; {
  const [rowData, setRowData] = useState([
    { make: &quot;Hyundai&quot;, model: &quot;Sonata&quot;, price: 2500 },
    { make: &quot;Kia&quot;, model: &quot;K5&quot;, price: 2700 },
  ]);

  const [columnDefs] = useState([
    { field: &quot;make&quot;, editable: true },
    { field: &quot;model&quot;, editable: true },
    { field: &quot;price&quot;, editable: true },
  ]);
  
  //저장 버튼과 연동
  const handleSave = () =&amp;gt; {
  	const updatedData = [];
    gridRef.current.api.forEachNode((node) =&amp;gt; {
    	updatedData.push(node.data);
     });
     console.log(&quot;저장할 데이터:&quot;, updatedData);
     // &amp;rarr; 서버로 전송
  };

  return (
    &amp;lt;div className=&quot;ag-theme-alpine&quot; style={{ height: 400, width: 600 }}&amp;gt;
      &amp;lt;AgGridReact
        rowData={rowData}
        columnDefs={columnDefs}
        onCellValueChanged={(params) =&amp;gt; {
        	console.log(&quot;변경된 행 데이터:&quot;, params.data);
            // 저장 API 호출하거나 로컬 상태 반영
        }}
        defaultColDef={{
          resizable: true,
          sortable: true,
        }}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* editable: true를 설정한 컬럼은 기본적으로 더블 클릭하면 편집 가능해집니다.&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>aggridreact</category>
      <category>react</category>
      <category>row변경</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/678</guid>
      <comments>https://redcow77.tistory.com/678#entry678comment</comments>
      <pubDate>Sun, 18 May 2025 07:29:43 +0900</pubDate>
    </item>
    <item>
      <title>ag-Grid-React 사용자 정의 셀 렌더러</title>
      <link>https://redcow77.tistory.com/677</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-17 오전 8.06.00.png&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;744&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1A9IM/btsN11iEo50/l0rTPztNJqFxCVAFTKt5c0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1A9IM/btsN11iEo50/l0rTPztNJqFxCVAFTKt5c0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1A9IM/btsN11iEo50/l0rTPztNJqFxCVAFTKt5c0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1A9IM%2FbtsN11iEo50%2Fl0rTPztNJqFxCVAFTKt5c0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;347&quot; data-filename=&quot;스크린샷 2025-05-17 오전 8.06.00.png&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;744&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-end=&quot;105&quot; data-start=&quot;86&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;105&quot; data-start=&quot;86&quot; data-ke-size=&quot;size26&quot;&gt;✅ 사용자 정의 셀 렌더러란?&lt;/h2&gt;
&lt;p data-end=&quot;234&quot; data-start=&quot;107&quot; data-ke-size=&quot;size16&quot;&gt;기본적으로 AgGridReact는 텍스트 기반으로 데이터를 셀에 출력합니다. 하지만 복잡한 UI(버튼, 이미지, 링크, 조건부 스타일 등)를 출력하고 싶은 경우, &lt;b&gt;React 컴포넌트를 셀 렌더러로 지정&lt;/b&gt;할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;292&quot; data-start=&quot;236&quot; data-ke-size=&quot;size16&quot;&gt;이는 일종의 &lt;b&gt;Cell View Layer&lt;/b&gt;를 개발자가 직접 구성할 수 있도록 해주는 구조입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;313&quot; data-start=&quot;299&quot; data-ke-size=&quot;size26&quot;&gt;  동작 방식 요약&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;488&quot; data-start=&quot;315&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;344&quot; data-start=&quot;315&quot;&gt;React로 &lt;b&gt;렌더러 컴포넌트&lt;/b&gt;를 작성한다.&lt;/li&gt;
&lt;li data-end=&quot;391&quot; data-start=&quot;345&quot;&gt;AgGridReact의 frameworkComponents에 등록한다.&lt;/li&gt;
&lt;li data-end=&quot;450&quot; data-start=&quot;392&quot;&gt;컬럼 정의(columnDefs)의 cellRenderer 속성으로 해당 컴포넌트를 지정한다.&lt;/li&gt;
&lt;li data-end=&quot;488&quot; data-start=&quot;451&quot;&gt;Ag-Grid가 각 셀에 대해 해당 컴포넌트를 mount한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;266&quot; data-start=&quot;263&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  AgGridReact 에서 prop를 통한 이벤트 처리 예제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1747436645101&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useState } from &quot;react&quot;;
import { AgGridReact } from &quot;ag-grid-react&quot;;
import ButtonRenderer from &quot;./ButtonRenderer&quot;;
import &quot;ag-grid-community/styles/ag-grid.css&quot;;
import &quot;ag-grid-community/styles/ag-theme-alpine.css&quot;;

const AgGridText = () =&amp;gt; {
	
	const [rowData] = useState([
        { make: &quot;Hyundai&quot;, model: &quot;Sonata&quot;, price: 25000 },
        { make: &quot;Kia&quot;, model: &quot;K5&quot;, price: 27000 },
	]);

	const [columnDefs] = useState([
		{ field: &quot;make&quot; },
		{ field: &quot;model&quot; },
		{ field: &quot;price&quot; },
		{
  			headerName: &quot;작업&quot;,
  			field: &quot;action&quot;,
  			cellRenderer: &quot;buttonRenderer&quot;, // 렌더러 지정
		},
	]);

	const ButtonRenderer = (props) =&amp;gt; {
		return (
            &amp;lt;button onClick={() =&amp;gt; props.context.handleRowClick(props.data)}&amp;gt;
              선택
            &amp;lt;/button&amp;gt;
          );
	};
    
	return (
    	&amp;lt;div className=&quot;ag-theme-alpine&quot; style={{ height: 400, width: 600 }}&amp;gt;
    	&amp;lt;AgGridReact
          rowData={rowData}
          columnDefs={columnDefs}
          frameworkComponents={{ buttonRenderer: ButtonRenderer }}
          context={{ handleRowClick: (data) =&amp;gt; console.log(data) }}
        /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>aggridreact</category>
      <category>frameworkcomponents</category>
      <category>react</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/677</guid>
      <comments>https://redcow77.tistory.com/677#entry677comment</comments>
      <pubDate>Sat, 17 May 2025 08:06:40 +0900</pubDate>
    </item>
    <item>
      <title>ag-Grid-React 라이브러리의 option</title>
      <link>https://redcow77.tistory.com/676</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-17 오전 8.06.00.png&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;744&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSu7jW/btsN198AvnF/k1vCRT8XGCnDaVvJyDButk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSu7jW/btsN198AvnF/k1vCRT8XGCnDaVvJyDButk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSu7jW/btsN198AvnF/k1vCRT8XGCnDaVvJyDButk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSu7jW%2FbtsN198AvnF%2Fk1vCRT8XGCnDaVvJyDButk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;347&quot; data-filename=&quot;스크린샷 2025-05-17 오전 8.06.00.png&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;744&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ag-grid-react는 React에서 강력한 데이터 그리드를 사용할 수 있게 해주는 라이브러리입니다. AgGridReact 컴포넌트를 사용하여 테이블을 만들고 다양한 기능을 쉽게 적용할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✅ 기본 사용 예시&lt;/h3&gt;
&lt;pre id=&quot;code_1747231081464&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useState } from &quot;react&quot;;
import { AgGridReact } from &quot;ag-grid-react&quot;;
import &quot;ag-grid-community/styles/ag-grid.css&quot;;
import &quot;ag-grid-community/styles/ag-theme-alpine.css&quot;;

const MyGrid = () =&amp;gt; {
  const [rowData] = useState([
    { make: &quot;Toyota&quot;, model: &quot;Celica&quot;, price: 35000 },
    { make: &quot;Ford&quot;, model: &quot;Mondeo&quot;, price: 32000 },
    { make: &quot;Porsche&quot;, model: &quot;Boxster&quot;, price: 72000 },
  ]);

  const [columnDefs] = useState([
    { field: &quot;make&quot; },
    { field: &quot;model&quot; },
    { field: &quot;price&quot; },
  ]);

  return (
    &amp;lt;div className=&quot;ag-theme-alpine&quot; style={{ height: 400, width: 600 }}&amp;gt;
      &amp;lt;AgGridReact rowData={rowData} columnDefs={columnDefs} /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-14 오후 10.58.37.png&quot; data-origin-width=&quot;1648&quot; data-origin-height=&quot;1330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvZxoQ/btsNWKWA5y4/U44OexUrskKlM8i2ySAiJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvZxoQ/btsNWKWA5y4/U44OexUrskKlM8i2ySAiJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvZxoQ/btsNWKWA5y4/U44OexUrskKlM8i2ySAiJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvZxoQ%2FbtsNWKWA5y4%2FU44OexUrskKlM8i2ySAiJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;750&quot; height=&quot;1330&quot; data-filename=&quot;스크린샷 2025-05-14 오후 10.58.37.png&quot; data-origin-width=&quot;1648&quot; data-origin-height=&quot;1330&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;1380&quot; data-start=&quot;1377&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1400&quot; data-start=&quot;1382&quot; data-ke-size=&quot;size26&quot;&gt;  다양한 기능 적용 예시&lt;/h2&gt;
&lt;pre id=&quot;code_1747231182202&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;AgGridReact
  rowData={rowData}
  columnDefs={columnDefs}
  defaultColDef={{
    sortable: true,
    filter: true,
    resizable: true,
  }}
  pagination={true}
  paginationPageSize={10}
  rowSelection=&quot;multiple&quot;
  animateRows={true}
  onRowClicked={(e) =&amp;gt; console.log(e.data)}
/&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>ac-grid-react</category>
      <category>grid라이브러리</category>
      <category>grid옵션</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/676</guid>
      <comments>https://redcow77.tistory.com/676#entry676comment</comments>
      <pubDate>Wed, 14 May 2025 23:01:10 +0900</pubDate>
    </item>
    <item>
      <title>하루 1%의 변화가 나의 인생을 바꾼다!!</title>
      <link>https://redcow77.tistory.com/675</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2025년 5월 9일 오후 04_48_56.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byK6DP/btsNRGM1zGk/bQOYxpg0Jc81LQAdOgGfU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byK6DP/btsNRGM1zGk/bQOYxpg0Jc81LQAdOgGfU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byK6DP/btsNRGM1zGk/bQOYxpg0Jc81LQAdOgGfU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyK6DP%2FbtsNRGM1zGk%2FbQOYxpg0Jc81LQAdOgGfU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;975&quot; data-filename=&quot;ChatGPT Image 2025년 5월 9일 오후 04_48_56.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1536&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-end=&quot;143&quot; data-start=&quot;106&quot;&gt;나를 변화시키는 8가지 루틴 &amp;ndash; 인생을 바꾸는 하루 관리법&lt;/h1&gt;
&lt;p data-end=&quot;274&quot; data-start=&quot;145&quot; data-ke-size=&quot;size16&quot;&gt;성공하는 사람과 그렇지 못한 사람의 차이는 &lt;b&gt;하루를 어떻게 보내는가&lt;/b&gt;에 달려 있습니다. 작은 습관 하나가 나를 완전히 바꿔 놓을 수 있습니다. 오늘부터 실천 가능한 8가지 루틴을 통해 당신의 인생에 놀라운 변화를 만들어 보세요.&lt;/p&gt;
&lt;p data-end=&quot;274&quot; data-start=&quot;145&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;307&quot; data-start=&quot;281&quot; data-ke-size=&quot;size26&quot;&gt;1. 오전 5시에 하루를 시작하기&amp;nbsp;&lt;/h2&gt;
&lt;p data-end=&quot;528&quot; data-start=&quot;308&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;하루를 2시간 먼저 시작하면, 남들보다 두 배 빠르게 앞서 나갈 수 있습니다.&amp;rdquo;&lt;/b&gt;&lt;br /&gt;아직 세상이 잠든 시간, 나만의 고요한 시간을 가지세요. 아침 5시에 하루를 시작하면 업무 효율성은 물론, 집중력이 극대화됩니다.&lt;br /&gt;가벼운 아침 운동과 차 한잔, 그리고 하루 계획을 세우는 이 시간은 하루 전체의 질을 결정합니다.&lt;/p&gt;
&lt;hr data-end=&quot;533&quot; data-start=&quot;530&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;558&quot; data-start=&quot;535&quot; data-ke-size=&quot;size26&quot;&gt;2. 하루의 마무리 5분 전  &lt;/h2&gt;
&lt;p data-end=&quot;762&quot; data-start=&quot;559&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;하루를 정리하는 5분, 내일의 성공을 준비하는 시간입니다.&amp;rdquo;&lt;/b&gt;&lt;br /&gt;잠들기 전, 오늘의 행복했던 순간 3가지를 떠올려보세요. 그리고 내일 꼭 이루고 싶은 목표를 짧게 기록해보는 겁니다.&lt;br /&gt;이 간단한 습관만으로도 머릿속 불안과 잡념을 줄이고, 깊고 안정된 수면을 취할 수 있습니다.&lt;br /&gt;✔️ Tip: '감사일기 + 내일의 한 문장 목표'를 매일 써보세요.&lt;/p&gt;
&lt;hr data-end=&quot;767&quot; data-start=&quot;764&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;798&quot; data-start=&quot;769&quot; data-ke-size=&quot;size26&quot;&gt;3. 하루 30분! 디지털 기술 배우기  &lt;/h2&gt;
&lt;p data-end=&quot;999&quot; data-start=&quot;799&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;AI 시대, 살아남기 위해서는 배워야 합니다.&amp;rdquo;&lt;/b&gt;&lt;br /&gt;단 30분, 디지털 기술을 익히는 데 투자해 보세요. ChatGPT, Notion, Python, 영상 편집 등 자신만의 디지털 무기를 갖추는 것이 중요합니다.&lt;br /&gt;이 습관은 곧 &lt;b&gt;생존력과 경쟁력&lt;/b&gt;을 만들어 줍니다.&lt;br /&gt;✔️ Tip: 하루 1개씩, 새로운 기능을 익히는 목표로 설정해보세요.&lt;/p&gt;
&lt;hr data-end=&quot;1004&quot; data-start=&quot;1001&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1037&quot; data-start=&quot;1006&quot; data-ke-size=&quot;size26&quot;&gt;4. 매일 1시간! 신체적 변화 갖기  &amp;zwj;♂️&lt;/h2&gt;
&lt;p data-end=&quot;1215&quot; data-start=&quot;1038&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;강한 몸이 강한 마음을 만듭니다.&amp;rdquo;&lt;/b&gt;&lt;br /&gt;달리기, 근력 운동, 요가 등 자신에게 맞는 운동을 꾸준히 실천하세요. 신체적인 변화는 곧 자신감과 정신적인 에너지를 불러옵니다.&lt;br /&gt;하루 1시간 운동은 당신의 삶을 한 단계 업그레이드할 열쇠입니다.&lt;/p&gt;
&lt;hr data-end=&quot;1220&quot; data-start=&quot;1217&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1250&quot; data-start=&quot;1222&quot; data-ke-size=&quot;size26&quot;&gt;5. 하루 10분! 명상의 시간  &amp;zwj;♀️&lt;/h2&gt;
&lt;p data-end=&quot;1428&quot; data-start=&quot;1251&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;바쁜 하루, 10분의 고요함으로 마음의 평화를 찾으세요.&amp;rdquo;&lt;/b&gt;&lt;br /&gt;명상은 단순한 휴식이 아닙니다. &lt;b&gt;불안과 스트레스를 줄이고&lt;/b&gt;, 사고력과 집중력을 향상시켜 줍니다.&lt;br /&gt;뇌를 쉬게 하는 10분은 결국 생산성을 끌어올리는 가장 강력한 도구입니다.&lt;br /&gt;✔️ Tip: 명상 앱을 활용하거나 심호흡에 집중해보세요.&lt;/p&gt;
&lt;hr data-end=&quot;1433&quot; data-start=&quot;1430&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1467&quot; data-start=&quot;1435&quot; data-ke-size=&quot;size26&quot;&gt;6. 하루 30분! 나를 설계하는 시간  &amp;zwj;♂️&lt;/h2&gt;
&lt;p data-end=&quot;1622&quot; data-start=&quot;1468&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;생각이 삶을 결정합니다.&amp;rdquo;&lt;/b&gt;&lt;br /&gt;산책은 단순한 운동이 아닙니다. 자신을 되돌아보고 미래를 설계하는 최고의 시간입니다.&lt;br /&gt;걸으며 떠오르는 아이디어, 정리되는 생각은 당신을 더 단단하고 긍정적으로 만듭니다.&lt;/p&gt;
&lt;hr data-end=&quot;1627&quot; data-start=&quot;1624&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1656&quot; data-start=&quot;1629&quot; data-ke-size=&quot;size26&quot;&gt;7. 하루 10페이지! 독서의 시간  &lt;/h2&gt;
&lt;p data-end=&quot;1850&quot; data-start=&quot;1657&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;책을 읽는 사람만이, 다음 세상을 준비할 수 있습니다.&amp;rdquo;&lt;/b&gt;&lt;br /&gt;지식은 곧 기회입니다. 하루 10페이지씩이라도 꾸준히 읽다 보면, 한 달이면 1~2권의 책을 완독할 수 있습니다.&lt;br /&gt;뇌를 자극하고 사고의 폭을 넓혀주는 독서는 여러분을 더 매력적인 사람으로 만들어 줍니다.&lt;br /&gt;✔️ Tip: 책 속 인상 깊은 문장을 한 줄 메모해 보세요.&lt;/p&gt;
&lt;hr data-end=&quot;1855&quot; data-start=&quot;1852&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1884&quot; data-start=&quot;1857&quot; data-ke-size=&quot;size26&quot;&gt;8. 완벽한 수면을 위한 나의 다짐  &lt;/h2&gt;
&lt;p data-end=&quot;2050&quot; data-start=&quot;1885&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;좋은 수면이 최고의 생산성입니다.&amp;rdquo;&lt;/b&gt;&lt;br /&gt;취침 3시간 전 음식 섭취 금지, 스마트폰 사용 줄이기, 마음을 가라앉히는 루틴을 만들어 보세요.&lt;br /&gt;수면의 질이 달라지면, 체력과 감정 컨트롤 능력, 집중력까지 모두 향상됩니다.&lt;br /&gt;✔️ Tip: 숙면을 돕는 나만의 루틴을 만들고 반복하세요.&lt;/p&gt;
&lt;p data-end=&quot;2050&quot; data-start=&quot;1885&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;2055&quot; data-start=&quot;2052&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2085&quot; data-start=&quot;2057&quot;&gt;✨ 결론: 하루 1%의 변화가 인생을 바꿉니다.&lt;/h1&gt;
&lt;p data-end=&quot;2200&quot; data-start=&quot;2087&quot; data-ke-size=&quot;size16&quot;&gt;오늘부터 하나의 루틴만이라도 시작해보세요. 중요한 건 &lt;b&gt;작은 실천을 꾸준히 이어가는 것&lt;/b&gt;입니다.&lt;br /&gt;변화는 생각보다 빠르게 찾아올 겁니다.  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Story/개인 주저리주저리(일기)</category>
      <category>6개월지키기</category>
      <category>8가지루틴</category>
      <category>성공하는삶</category>
      <category>인생의변화</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/675</guid>
      <comments>https://redcow77.tistory.com/675#entry675comment</comments>
      <pubDate>Fri, 9 May 2025 16:53:21 +0900</pubDate>
    </item>
    <item>
      <title>컴퓨터 활용1급 필기 주차별 학습테이블</title>
      <link>https://redcow77.tistory.com/674</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;30일 동안의 주차별 요일별 학습 타임테이블&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평일은 하루 1~2시간 주말은 3시간 기준으로 맞춰서 구성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 취약한 스프레드시트를 각 주차마다 비중을 조정해서 반영한 학습테이블&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-07 오전 12.03.33.png&quot; data-origin-width=&quot;1608&quot; data-origin-height=&quot;978&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/F8lnR/btsNMb6R8if/vlQ8XABfAfpuhQ8FlJISNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/F8lnR/btsNMb6R8if/vlQ8XABfAfpuhQ8FlJISNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/F8lnR/btsNMb6R8if/vlQ8XABfAfpuhQ8FlJISNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FF8lnR%2FbtsNMb6R8if%2FvlQ8XABfAfpuhQ8FlJISNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;750&quot; height=&quot;456&quot; data-filename=&quot;스크린샷 2025-05-07 오전 12.03.33.png&quot; data-origin-width=&quot;1608&quot; data-origin-height=&quot;978&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-07 오전 12.04.08.png&quot; data-origin-width=&quot;1616&quot; data-origin-height=&quot;978&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bs3PCJ/btsNLAlESCA/ZpVVXzKMJjdSGlLbmAUn80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bs3PCJ/btsNLAlESCA/ZpVVXzKMJjdSGlLbmAUn80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bs3PCJ/btsNLAlESCA/ZpVVXzKMJjdSGlLbmAUn80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbs3PCJ%2FbtsNLAlESCA%2FZpVVXzKMJjdSGlLbmAUn80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;424&quot; data-filename=&quot;스크린샷 2025-05-07 오전 12.04.08.png&quot; data-origin-width=&quot;1616&quot; data-origin-height=&quot;978&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-07 오전 12.04.39.png&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;978&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LciJN/btsNMdDxJKc/Tggb1DrnvUmPebwO5Rmw6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LciJN/btsNMdDxJKc/Tggb1DrnvUmPebwO5Rmw6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LciJN/btsNMdDxJKc/Tggb1DrnvUmPebwO5Rmw6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLciJN%2FbtsNMdDxJKc%2FTggb1DrnvUmPebwO5Rmw6K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;418&quot; data-filename=&quot;스크린샷 2025-05-07 오전 12.04.39.png&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;978&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-07 오전 12.05.19.png&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bs3pOs/btsNLbsVg4i/jKsL6LU8i6Nk2PY8tYeEsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bs3pOs/btsNLbsVg4i/jKsL6LU8i6Nk2PY8tYeEsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bs3pOs/btsNLbsVg4i/jKsL6LU8i6Nk2PY8tYeEsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbs3pOs%2FbtsNLbsVg4i%2FjKsL6LU8i6Nk2PY8tYeEsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;438&quot; data-filename=&quot;스크린샷 2025-05-07 오전 12.05.19.png&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매일 체크하면서 사용이 가능한 스터디 플래너 양식도 함께 학습을 하게 되면 좋을것 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-07 오전 12.06.54.png&quot; data-origin-width=&quot;1632&quot; data-origin-height=&quot;658&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y9Z0a/btsNMyOgbUy/Phal1Q4UmBoDcPbDwexbn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y9Z0a/btsNMyOgbUy/Phal1Q4UmBoDcPbDwexbn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y9Z0a/btsNMyOgbUy/Phal1Q4UmBoDcPbDwexbn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy9Z0a%2FbtsNMyOgbUy%2FPhal1Q4UmBoDcPbDwexbn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;242&quot; data-filename=&quot;스크린샷 2025-05-07 오전 12.06.54.png&quot; data-origin-width=&quot;1632&quot; data-origin-height=&quot;658&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Etc</category>
      <category>30일합격</category>
      <category>스터디플래너</category>
      <category>컴퓨터활용1급</category>
      <category>학습테이블</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/674</guid>
      <comments>https://redcow77.tistory.com/674#entry674comment</comments>
      <pubDate>Wed, 7 May 2025 00:08:34 +0900</pubDate>
    </item>
    <item>
      <title>컴퓨터 활용1급 필기 학습테이블</title>
      <link>https://redcow77.tistory.com/673</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;컴퓨터 활용 1급 자격증 필기 30일 학습 테이블&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직장인과 아이들이 있는 가장이라 하루에 평일 1~2시간 주말에는 3시간 시간 투자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 IT개발자로 컴퓨터 일반, 테이터베이스 일반 학습 비중보다는 스프레드시트 비중을 높인 학습테이블&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-02 오후 1.29.18.png&quot; data-origin-width=&quot;1614&quot; data-origin-height=&quot;1684&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MLnkJ/btsNIRtNcds/9EsICbv4tgtogVD2evkA0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MLnkJ/btsNIRtNcds/9EsICbv4tgtogVD2evkA0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MLnkJ/btsNIRtNcds/9EsICbv4tgtogVD2evkA0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMLnkJ%2FbtsNIRtNcds%2F9EsICbv4tgtogVD2evkA0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;730&quot; data-filename=&quot;스크린샷 2025-05-02 오후 1.29.18.png&quot; data-origin-width=&quot;1614&quot; data-origin-height=&quot;1684&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추천자료는 시나공 컴퓨터활용능력 1급 필기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제풀이 Web 사이트로는&amp;nbsp;&lt;br /&gt;문제은행 - &lt;a href=&quot;https://www.cbtbank.kr/category/%EC%BB%B4%ED%93%A8%ED%84%B0%ED%99%9C%EC%9A%A9%EB%8A%A5%EB%A0%A5-1%EA%B8%89&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.cbtbank.kr/category/%EC%BB%B4%ED%93%A8%ED%84%B0%ED%99%9C%EC%9A%A9%EB%8A%A5%EB%A0%A5-1%EA%B8%89&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최강자격증 기출문제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.comcbt.com/xe/c1#google_vignette&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.comcbt.com/xe/c1#google_vignette&lt;/a&gt;&lt;/p&gt;</description>
      <category>프로그래밍/Etc</category>
      <category>자격증</category>
      <category>컴퓨터활용능력1급</category>
      <category>학습테이블</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/673</guid>
      <comments>https://redcow77.tistory.com/673#entry673comment</comments>
      <pubDate>Fri, 2 May 2025 13:36:48 +0900</pubDate>
    </item>
    <item>
      <title>어른이 되면 철이 든다고!!??</title>
      <link>https://redcow77.tistory.com/672</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_8219.JPEG&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IhlxK/btsNGRPI9qT/C4iW0nQiGdE4BjN8jjA8D0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IhlxK/btsNGRPI9qT/C4iW0nQiGdE4BjN8jjA8D0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IhlxK/btsNGRPI9qT/C4iW0nQiGdE4BjN8jjA8D0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIhlxK%2FbtsNGRPI9qT%2FC4iW0nQiGdE4BjN8jjA8D0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;560&quot; data-filename=&quot;IMG_8219.JPEG&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1792&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1 style=&quot;background-color: #ffffff; color: #5c5c5c; text-align: start;&quot; data-sourcepos=&quot;1:1-1:50&quot;&gt;나이와 성숙에 대한 흔히들 하는 생각들...&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다들 어릴 적 부터 나이가 들어서 어른이 되는 날만을 손꼽아 기다렸습니다. 아버지를 보며 세상의 풍파를 여유롭게 헤쳐나가며, 어떤 상황에서도 흔들리지 않는 성숙한 어른의 모습을 상상했습니다. 하지만 내가 겪고 있는 현실은 그와는 너무 다릅니다. 문득 뒤돌아보면, 어릴 적 꿈꿔왔던 이상적인 어른의 모습과는 거리가 먼 자신을 발견하게 됩니다. 오히려 주변의 어른들을 보면, 늘 조용하고 차분한 모습에 '이제 철이 들었구나'라고 생각하기 쉽지만, 자세히 보게 되면 하루하루 버텨내느라 기진맥진한 경우가 더 많다는 것을 깨닫게 됩니다.&lt;span&gt; &lt;/span&gt;그들의 조용한 모습은 성숙함보다는 삶의 무게에 지친 피로감의 표현일 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 현재 생각하고 있는 어른의 성숙함은 침묵과 차분함 뒤에는, 실로 엄청난 책임감과 압박감이 숨어있다고 생각합니다. 직장에서의 끊임없는 업무, 예측 불가능한 경제 상황, 그리고 가족을 부양해야 하는 무거운 짐까지, 어른들은 다양한 종류의 스트레스와 싸우며 하루하루를 살아갑니다. 이러한 현실 속에서, 과거처럼 활기 넘치고 감정적으로 반응하기보다는 에너지를 비축하고 불필요한 소모를 줄이기 위해 자연스럽게 조용해지는 것인지도 모릅니다.&lt;span&gt;&lt;/span&gt; 마치 고장 난 기계처럼, 삐걱거리는 몸과 마음을 이끌고 겨우 하루를 마무리하는 어른들에게, 주변의 '철들었다'는 평가는 어쩌면 그들의 고단함을 제대로 이해하지 못한 채 섣불리 내리는 판단일 수 있습니다. 진정한 성숙함은 단순히 조용해지는 것을 넘어, 이러한 어려움 속에서도 자신을 다독이고 앞으로 나아가는 내면의 힘에 있는 것은 아닐까 라고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 style=&quot;background-color: #ffffff; color: #5c5c5c; text-align: start;&quot; data-sourcepos=&quot;1:1-1:50&quot;&gt;성숙함의 대한 오해!&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 진정으로 성숙한 어른의 모습은 어떤 것일까? 단순히 겉으로 보이는 침착함이 아니라, 자신의 감정을 제대로 이해하고 조절하는 능력, 타인의 어려움에 공감하는 마음, 그리고 끊임없이 자신을 성찰하고 발전시키려는 노력이 진정한 성숙함에 더 가까울것이라고 생각됩니다. 나이가 들수록 우리는 자신의 부족함을 인정하고, 타인의 허물을 너그럽게 이해하며 함께 살아가는 지혜를 배워나가는 것이 진정한 어른의 모습이라고 봅니다.&amp;nbsp;겉으로는 완벽해 보이는 어른일지라도, 속으로는 여전히 불안하고 흔들릴 수 있다는 것을 인정하는 겸손함, 그리고 세상의 어려움 속에서도 꿋꿋하게 자신의 길을 걸어가는 회복탄력성이야말로 진정한 어른의 모습일 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국, 우리가 어른이 되면서 보이는 조용한 모습이 항상 성숙함의 증거는 아닐 수 있습니다. 때로는 삶의 무게에 지쳐 에너지를 소진한 결과일 수도 있다는 점을 기억해야 합니다.&lt;span&gt;&lt;/span&gt; 겉으로 보이는 모습에 쉽게 판단하기보다는, 그들이 짊어진 삶의 무게를 이해하고 공감하려는 노력이 필요합니다. 어쩌면 나, 너 , 그리고 우리 모두는 겉으로는 어른의 탈을 쓰고 있지만, 속으로는 여전히 서툴고 미성숙한 아이의 모습을 간직하고 있는지도 모릅니다. 그러므로, 서로에게 더 따뜻한 시선을 보내고, 진정한 성숙의 의미를 함께 고민하며 나아가는 것이 훨씬 더 의미 있는 일이 아닐까 라고 생각합니다.&lt;/p&gt;</description>
      <category>Story/개인 주저리주저리(일기)</category>
      <category>나이</category>
      <category>성숙함</category>
      <category>착각</category>
      <category>철들었네</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/672</guid>
      <comments>https://redcow77.tistory.com/672#entry672comment</comments>
      <pubDate>Fri, 2 May 2025 13:17:26 +0900</pubDate>
    </item>
    <item>
      <title>관계의 노력 그리고 함께하는 삶의 중요성</title>
      <link>https://redcow77.tistory.com/671</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_8223.JPEG&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1317&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6GOvq/btsNF7ZaSpz/TPUVRvLGFVPPOVLpxgTak1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6GOvq/btsNF7ZaSpz/TPUVRvLGFVPPOVLpxgTak1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6GOvq/btsNF7ZaSpz/TPUVRvLGFVPPOVLpxgTak1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6GOvq%2FbtsNF7ZaSpz%2FTPUVRvLGFVPPOVLpxgTak1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;549&quot; data-filename=&quot;IMG_8223.JPEG&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1317&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-sourcepos=&quot;1:1-1:50&quot;&gt;당신만 애쓰는 관계, 왜 그렇게 힘들까?&lt;/h1&gt;
&lt;h1 data-sourcepos=&quot;1:1-1:50&quot;&gt;노력해도 변하지 않는 관계에 대한 솔직한 이야기&lt;/h1&gt;
&lt;p data-sourcepos=&quot;3:1-3:603&quot; data-ke-size=&quot;size16&quot;&gt;끊임없이 관계 개선을 위해 노력하지만, 늘 혼자 외로운 싸움을 하는 듯한 기분이 드는건 왜일까? 마치 나 홀로 짊어진 짐처럼 느껴지는 관계 속에서 당신의 마음은 과연 평안한가요? 상대방의 무관심이나 소극적인 태도에 지쳐 '내가 이만큼 노력하는데 왜 나만 힘들까?'라는 질문을 수도 없이 던지며 생활하고 있습니다. 헌신과 배려를 쏟아부어도 돌아오는 것은 공허함과 서운함뿐이라면, 그 관계는 나에게는 어떤 의미일까? &amp;nbsp;&quot;혼자하는 관계는 외롭고 서럽다&quot;고 표현한 것처럼, 당신의 짝사랑과 같은 노력은 당신의 마음을 좀먹고 있을 수 있습니다. &quot;나는 상대를 이만큼 생각하고 배려하는데, 왜 그 사람은 내 마음을 조금도 알아주지 않는 거지?&quot;, &quot;왜 나의 친절을 당연한 일로 받아들이는 거지?&quot; 이와 같은 자문자답은 당신을 절망과 고립감에 빠뜨릴 수 있습니다. 시간이 흐르면서 상대방의 애정이 식어가는 것을 느끼고, 홀로 그 애정을 갈구하게 되는 상황 더욱 힘겹게 느껴지며 살아갈것입니다. 당신의 다양한 감정을 표현하지 못하고 혼자 끙끙 앓는 동안, 상대방은 당신의 진심을 알 수 없을지도 모릅니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-sourcepos=&quot;3:1-3:603&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-01 오전 12.24.56.png&quot; data-origin-width=&quot;1488&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I7aV3/btsNIjccBDK/EsbBvM7WJ8lKr55vEuH1T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I7aV3/btsNIjccBDK/EsbBvM7WJ8lKr55vEuH1T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I7aV3/btsNIjccBDK/EsbBvM7WJ8lKr55vEuH1T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI7aV3%2FbtsNIjccBDK%2FEsbBvM7WJ8lKr55vEuH1T0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1488&quot; height=&quot;468&quot; data-filename=&quot;스크린샷 2025-05-01 오전 12.24.56.png&quot; data-origin-width=&quot;1488&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-sourcepos=&quot;3:1-3:603&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-sourcepos=&quot;3:1-3:603&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-sourcepos=&quot;3:1-3:603&quot; data-ke-size=&quot;size16&quot;&gt;그렇다면 건강하고 좋은 관계는 어떤 모습일까? 좋은 관계는 한쪽만의 헌신이 아닌, 함께 노력해서 만들어가는 온도와 같습니다. &quot;관계는 함께 하는 상호작용이다. 내가 있고 네가 있어야지만 관계가 만들어진다&quot;고 강조한 것처럼, 서로가 존재해야 비로소 관계가 성립됩니다. 상대방을 존중하고 그의 이야기에 귀 기울이며, 갈등을 해결하려는 노력이 지속될 때 관계는 더욱 단단해질 수 있습니다.&lt;span&gt;&lt;/span&gt; 부부 관계를 예로 들자면, 서로의 상태를 함께 평가하고 솔직한 느낌과 생각을 나누며, 관계가 왜 어려워졌는지 함께 분석하고 개선 방안을 함께 모색하는 것이 중요합니다.&lt;span&gt;&lt;/span&gt; &quot;소통과 존중,&quot; &quot;관심과 이해,&quot; &quot;솔직한 의사소통,&quot; 그리고 &quot;시간과 노력 투자&quot; &lt;span&gt;&lt;/span&gt;는 건강한 관계를 위한 필수적인 요소입니다. 서로 존중하는 마음으로 진심으로 경청하는 &lt;span&gt;&lt;/span&gt; 대화는 관계를 더욱 깊게 만듭니다. 건강한 관계는 또한 서로를 존중하고 수평적인 태도를 가지며, 상대방의 마음을 헤아릴 줄 아는 능력을 포함합니다.&lt;span&gt;&lt;/span&gt;&amp;nbsp;위의 표는 혼자 노력하는 관계와 서로 노력하는 건강한 관계의 주요 차이점을 보여줍니다&lt;/p&gt;
&lt;p data-sourcepos=&quot;3:1-3:603&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-sourcepos=&quot;3:1-3:603&quot; data-ke-size=&quot;size16&quot;&gt;오랜 시간 노력했음에도 불구하고 관계가 개선될 기미가 보이지 않는다면, 이제는 멈춰야 할 때인지도 모릅니다. 특히 &lt;span&gt;&lt;/span&gt;에서 &quot;더는 혼자 잘해주고 상처받지 마라. 상대가 원하지 않는 배려를 베풀고 되돌아오지 않는 친절을 기대하지 말자&quot;고 조언하는 것처럼, 일방적인 노력은 결국 당신을 지치게 만들 뿐입니다. &quot;혼자하는 관계는 버겁다. 상대와 소통하지 않는 관계&quot; &lt;span&gt;&lt;/span&gt;라는 말처럼, 소통조차 제대로 이루어지지 않는 관계는 지속되기 어렵습니다. 만약 당신이 미련을 두고 있다면, 용기를 내어 변화를 시도해 볼 수도 있지만 &lt;span&gt;&lt;/span&gt;, 밑 빠진 독에 물을 붓는 것처럼 느껴진다면 그만두는 것이 현명할 수 있습니다.&lt;span&gt;&lt;/span&gt; 당신의 소중한 감정을 더 이상 당신의 사람이 아닌 사람에게 쏟을 필요는 없습니다.&lt;span&gt;&lt;/span&gt; 관계에서 어느 한쪽도 움직이지 않는다면 행복을 얻을 수 없습니다.&lt;span&gt;&lt;/span&gt; 혼자만의 노력으로 지친 당신은 더 행복한 관계를 찾아 나설 자격이 있습니다. 당신이 변화를 선택했을 때 떠나가는 사람이라면, 어차피 당신 곁에 머물 사람이 아니었을 가능성이 큽니다.&lt;span&gt;&lt;/span&gt; 이제 당신의 행복을 최우선으로 생각하고, 서로에게 긍정적인 영향을 주고받는 건강한 관계를 찾아 나서는 가장 중요한게 아닐까 생각됩니다.&lt;/p&gt;</description>
      <category>Story/개인 주저리주저리(일기)</category>
      <category>관계</category>
      <category>노력</category>
      <category>좋은관계</category>
      <category>함께</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/671</guid>
      <comments>https://redcow77.tistory.com/671#entry671comment</comments>
      <pubDate>Thu, 1 May 2025 00:31:48 +0900</pubDate>
    </item>
    <item>
      <title>[TypeScript] 타입스크립트의 타입호환</title>
      <link>https://redcow77.tistory.com/670</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-01 오후 12.41.11.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;856&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m8YoR/btsBvn0fjv3/xH2pEaLk2SUd2u1iPn4Vz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m8YoR/btsBvn0fjv3/xH2pEaLk2SUd2u1iPn4Vz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m8YoR/btsBvn0fjv3/xH2pEaLk2SUd2u1iPn4Vz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm8YoR%2FbtsBvn0fjv3%2FxH2pEaLk2SUd2u1iPn4Vz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1526&quot; height=&quot;856&quot; data-filename=&quot;스크린샷 2023-12-01 오후 12.41.11.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;856&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입스크립트(TypeScript)의 타입 호환이란 타입스크립트 코드에서 특정 타입이 다른 타입과 잘 맞는지를 의미합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기본적으로 자바스크립트는 객체 리터럴이나 익명 함수 등을 사용하기 때문에 명시적으로 타입을 지정하는 것보다는 코드의 구조 관점에서 타입을 지정하는 것이 더 올바른 코드 방식입니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1701924301490&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface user {
	name: string;
}

inteface login {
	name: string;
}

let i: user;
i = new login();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;구조적 타이핑 예시&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;구조적 타이핑이란 코드 구조 관점에서 타입이 서로 호환되는지의 여부를 판단하는 것입니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1701924919346&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface Users {
  name: string;
}

let loginName: Users;

// 타입스크립트가 추론한 y의 타입은 { name: string; location: string; } 입니다.
let loginUsers = { name: &quot;redcow7&quot;, location: &quot;Seoul&quot; };
loginName = loginUsers;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;Soundness(건전성)란?&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;타입스크립트(TypeScript)에서 기본적으로 타입 안정성을 지키려고 하는것을 말합니다. 컴파일 시점에 타입을 추론할 수 없는 특정 타입에 대해서는 '일단 안전하다'라고 보는 특성이 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프로그래밍 언어의 설계는 단순성, 사용성, 건전성의 절충 이기 때문입니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;Enum 타입 호환 주의 사항&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Enum 타입은 number 타입과 호환이 가능하지만, Enum 타입끼리는 호환이 불가능합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701925175522&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;enum Status { Ready, Waiting };
enum Color { Red, Blue, Green };

let status = Status.Ready;
status = Color.Green;  // Error&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;Class 타입 호환 주의 사항&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Class 타입은 Class 타입끼리 비교할 때 스태틱 멤버(static member)와 생성자(constructor)를 제외하고 속성만 비교를 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701925309285&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class User {
  handSize: number;
  constructor(name: string, numHand: number) { }
}

class LoginUser {
  handSize: number;
  constructor(numHand: number) { }
}

let a: User;
let s: LoginUser;

a = s;  // OK
s = a;  // OK&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;제네릭 타입 호환(Generics)&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Generics은 제네릭 타입 간의 호환 여부를 판단할때 타입 인자가 속성에 할당되었는지를 기준으로 판단합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701925447031&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface Empty&amp;lt;T&amp;gt; {
}
let x: Empty&amp;lt;number&amp;gt;;
let y: Empty&amp;lt;string&amp;gt;;

x = y;  // OK, because y matches structure of x


interface NotEmpty&amp;lt;T&amp;gt; {
  data: T;
}
let x: NotEmpty&amp;lt;number&amp;gt;;
let y: NotEmpty&amp;lt;string&amp;gt;;

x = y;  // Error, because x and y are not compatible&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://joshua1988.github.io/ts/guide/type-compatibility.html#class-%ED%83%80%EC%9E%85-%ED%98%B8%ED%99%98-%EC%A3%BC%EC%9D%98-%EC%82%AC%ED%95%AD&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://joshua1988.github.io/ts/guide/type-compatibility.html#class-%ED%83%80%EC%9E%85-%ED%98%B8%ED%99%98-%EC%A3%BC%EC%9D%98-%EC%82%AC%ED%95%AD&lt;/a&gt;&lt;/p&gt;</description>
      <category>프로그래밍/Javascript</category>
      <category>JavaScript</category>
      <category>Soundness</category>
      <category>TypeScript</category>
      <category>자바스크립트</category>
      <category>타입스크립트</category>
      <category>타입호환</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/670</guid>
      <comments>https://redcow77.tistory.com/670#entry670comment</comments>
      <pubDate>Thu, 7 Dec 2023 14:05:25 +0900</pubDate>
    </item>
    <item>
      <title>[TypeScript] 타입스크립트의 인터페이스란?</title>
      <link>https://redcow77.tistory.com/669</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-01 오후 12.41.11.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;856&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bANz7o/btsBrNkm88C/LZVUwxVkPUuybvZ4hEdnF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bANz7o/btsBrNkm88C/LZVUwxVkPUuybvZ4hEdnF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bANz7o/btsBrNkm88C/LZVUwxVkPUuybvZ4hEdnF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbANz7o%2FbtsBrNkm88C%2FLZVUwxVkPUuybvZ4hEdnF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1526&quot; height=&quot;856&quot; data-filename=&quot;스크린샷 2023-12-01 오후 12.41.11.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;856&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입스크립트(TypeScript) 코드의 인터페이스는 객체 내의 프로퍼티를 정의하는 방법입니다. 변수를 선언할 때마다 각각 타입을 지정하는 방법보다 인터페이스를 사용하는 방법이 편하고 재사용도 가능하기에 자주 사용하는 문법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;타입스크립트(TypeScript) 인터페이스란?&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프로그래밍 코드에서 상호간에 정의한 약속 혹은 규칙을 인터페이스라고 합니다. 타입스크립트(TypeScript)에서 인터페이스는 다음과 같은 범위에서의 약속을 정의가 가능합니다. 인터페이스를 통하여 값이 따라야 할 제약을 타입으로 표현 가능하며, 인터페이스 타입을 통하여 값의 형태를 서술이 가능합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. 클래스&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. 배열과 객체를 접근하는 방법&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3. 함수의 파라미터&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;4. 객체의 스펙(속성과 속성의 타입)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;5. 함수의 스펙(파라미터, 반환 타입)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1701839263540&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//옵션 속성
interface 인터페이스_name {
	속성?: 타입;
}

//예제
interface InterfaceName {
	name: string;
        age: number;
}

//읽기전용
interface UserName {
	name: string;
    	readonly age: number;
}

//함수 인터페이스
interface GetUser {
	(user, user): string;
}

//클래스 타입 인터페이스
interface WorldName {
  name: string;
  nameTest(test: string): void;
}

class myWorld implements WorldName {
  name: string = 'redcow7';
  nameTest(b: string) {
    this.name = b;
  }
  constructor() {}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이외에도 인터페이스 간 확장되는 인터페이스 확장 형태와 자바스크립트의 유연하고 동적인 타입 특성에 따라 인터페이스 여러 가지 타입을 조합 가능한 하이브리드 타입 형태 인터페이스가 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1701840245461&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//인터페이스 확장
interface User {
  name: string;
}
interface LoginUser extends User {
  id: string;
}
let fe = {} as LoginUser;
fe.name = 'redcow7';
fe.id = 'abcd';


//하이브리드 타입 인터페이스
interface LoginUser {
  (name: string): string;
  id: string;
  password(): void;
}

function myUser(): LoginUser {
  let my = (function(name: string) {}) as LoginUser;
  my.id = 'abcd';
  my.password = function() {};
  return my;
}

let loginStatus = myUser ();
loginStatus('redcow7');
loginStatus.id = 'bbbbb';
loginStatus.password();&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/Javascript</category>
      <category>Interface</category>
      <category>javscript</category>
      <category>TypeScript</category>
      <category>인터페이스</category>
      <category>자바스크립트</category>
      <category>타입스크립트</category>
      <category>타입스크립트함수</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/669</guid>
      <comments>https://redcow77.tistory.com/669#entry669comment</comments>
      <pubDate>Wed, 6 Dec 2023 14:25:41 +0900</pubDate>
    </item>
    <item>
      <title>[TypeScript] 타입스크립트의 고유문법</title>
      <link>https://redcow77.tistory.com/668</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-01 오후 12.41.11.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;856&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tcDxd/btsBjpKX5Gn/GtsWm9jFkgcVj4KDev6XUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tcDxd/btsBjpKX5Gn/GtsWm9jFkgcVj4KDev6XUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tcDxd/btsBjpKX5Gn/GtsWm9jFkgcVj4KDev6XUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtcDxd%2FbtsBjpKX5Gn%2FGtsWm9jFkgcVj4KDev6XUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1526&quot; height=&quot;856&quot; data-filename=&quot;스크린샷 2023-12-01 오후 12.41.11.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;856&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;타입스크립트(TypeScript) 고유문법&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. 타입 주석과 타입 추론&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;타입 주석이란 변수 뒤에 콜론(:)과 타입 이름을 말합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 타입 주석을 생략도 가능합니다. 타입 부분이 생략되면 대입 연산자(=)의 오른쪽 값을 분석하여 변수의 타입을 결정하는데 이를 타입 추론이라고 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;타입스크립트(TypeScript)의 타입 추론 기능은 자바스크립트 코드와 호환성을 보장하는데 큰 역활을 하며, 이 때문에 자바스크립트로 작성된 '. js' 파일을 확장자만 '. ts'의 확장자로 바꾸게 되면 타입스크립트 환경에서도 동작이 가능합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701734865518&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//타입 주석
let num: number = 1;

//타입 추론
let n = 10;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. 튜플(Tuple)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;튜플(Tuple)은 파이썬과 같은 몇몇 프로그래밍 언어에서 사용됩니다. 배열과 튜플(Tuple)의 차이점은 저장되는 데이터 타입이 모두 같으면 배열, 다르면 튜플(Tuple) 입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701735008877&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//배열
let numArr : number[] =[10, 9, 8];
let arr: Array&amp;lt;number&amp;gt; = [5, 6, 4];

//튜플(Tuple)
let tuple: [number, string] = [10, 'Hello'];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 제네릭 타입&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 타입을 한 번에 사용할 수 있게 해주는 타입을 제네릭 타입이라고 합니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1701735481511&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Container&amp;lt;A&amp;gt; {
	constructor(public value: A) { }
}

let numContainer: Container&amp;lt;number&amp;gt; = new Container&amp;lt;number&amp;gt;(1);
let strContainer: Container&amp;lt;string&amp;gt; = new Container&amp;lt;string&amp;gt;('Hello World');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 대수 타입&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대수 타입이란, 다른 자료형의 값을 가지고 있는 자료형을 의미합니다. 대수 타입에는 크게 합집합(union) 타입과 교집합(intersection) 타입 두 가지 타입이 있으며, 합집합 타입은 '|' 기호를 사용하며 교집합 타입은 '&amp;amp;' 기호를 사용하여 여러 타입을 결합할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ADT란, 추상 데이터 타입(abstract data type)을 의미하기도 하지만 대수 타입이라는 의미로도 사용됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701736976903&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//합집합 (union)
type NumOrStr = number | string;

//교집합 (intersection)
type numAndStr = number &amp;amp; String;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/Javascript</category>
      <category>JavaScript</category>
      <category>TypeScript</category>
      <category>고유문법</category>
      <category>대수타입</category>
      <category>자바스크립트</category>
      <category>제네릭타입</category>
      <category>타입스크립트</category>
      <category>타입주석</category>
      <category>타입추론</category>
      <category>튜플</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/668</guid>
      <comments>https://redcow77.tistory.com/668#entry668comment</comments>
      <pubDate>Tue, 5 Dec 2023 09:45:38 +0900</pubDate>
    </item>
    <item>
      <title>[TypeScript] 타입스크립트의 기초문법</title>
      <link>https://redcow77.tistory.com/667</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-01 오후 12.41.11.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;856&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ECTec/btsBl7WXGRo/bim7VR7LyjPCBOQURkPaE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ECTec/btsBl7WXGRo/bim7VR7LyjPCBOQURkPaE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ECTec/btsBl7WXGRo/bim7VR7LyjPCBOQURkPaE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FECTec%2FbtsBl7WXGRo%2Fbim7VR7LyjPCBOQURkPaE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1526&quot; height=&quot;856&quot; data-filename=&quot;스크린샷 2023-12-01 오후 12.41.11.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;856&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입스크립트(TypeScript) 코드에서는 어떠한 변수 또는 값의 타입을 표기하기 위하여 타입 표기를 사용합니다. 타입 표기는 식별자 또는 값 뒤에 콜론(:)을 붙여서 value:type 의 형태로 표기합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;타입스크립트(TypeScript) 기본 타입&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. Boolean - 타입의 진위 값을&amp;nbsp; 확인하기 위한 타입, 참 또는 거짓을 나타내는 타입입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701681876271&quot; class=&quot;groovy&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let status: boolean = true;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. Number - 숫자를 나타내는 타입입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701681876272&quot; class=&quot;xquery&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let count: number = 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. String - 문자열을 나타내는 타입입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701681876272&quot; class=&quot;armasm&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let str: string = &quot;Hello World&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Array - 배열을 나타내는 타입으로 요소의 타입까지 정의해야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701681876272&quot; class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let arr: number[] = [7,8,9];
let arr: Array&amp;lt;number&amp;gt; = [5,6,4];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. null / undefined - null, undefined 각각의 타입을 나타내며 하나의 값만을 갖는 타입입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701681876273&quot; class=&quot;javascript&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let nullVal: null = null;
let undefinedVal: undefined = undefined;

//type Error
let nullVal: null = undeefined;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. Tuple - Tuple은 배열의 길이가 고정되고 각 요소의 타입이 지정되어 있는 배열 형식을 의미하는 타입입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701681876273&quot; class=&quot;typescript&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let arr: [number,string] = [1,'Hello World'];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. any - 모든 타입을 할당할 수 있는 타입형태입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701681876274&quot; class=&quot;typescript&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let arr: any = [true, 5, 'hello'];
let str: any = 'Hello World';
let num: any = 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. void - 반환 값이 없는 함수의 반환 타입형태입니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1701681876274&quot; class=&quot;actionscript&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function test(): void {
	console.log(&quot;Hello World&quot;);
}

function returnVoid() : void {
	return;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9. Never - 무한반복을 뜻하는 함수의 타입을 뜻합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701681876275&quot; class=&quot;actionscript&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function noEnd(): never {

	while(true){
    
    	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Javascript</category>
      <category>JavaScript</category>
      <category>TypeScript</category>
      <category>자바스크립트</category>
      <category>타입</category>
      <category>타입스크립트</category>
      <category>타입스크립트기본타입</category>
      <category>타입스크립트기초문법</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/667</guid>
      <comments>https://redcow77.tistory.com/667#entry667comment</comments>
      <pubDate>Mon, 4 Dec 2023 18:25:28 +0900</pubDate>
    </item>
    <item>
      <title>[TypeScript] 타입스크립트는 무엇일까?</title>
      <link>https://redcow77.tistory.com/666</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-01 오후 12.41.11.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;856&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AVLRk/btsBl5ERMS4/GKrTkbRQ8pSaiaLMH8YjJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AVLRk/btsBl5ERMS4/GKrTkbRQ8pSaiaLMH8YjJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AVLRk/btsBl5ERMS4/GKrTkbRQ8pSaiaLMH8YjJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAVLRk%2FbtsBl5ERMS4%2FGKrTkbRQ8pSaiaLMH8YjJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1526&quot; height=&quot;856&quot; data-filename=&quot;스크린샷 2023-12-01 오후 12.41.11.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;856&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트에는 현재 세 가지 종류가 있습니다. 웹 브라우저에 동작되는 표준 자바스크립트 ES5(ECMA Script 5)와 2015년부터 새로운 버전을 발표하고 있는 ESNext(ES6), 그리고 ESNext에 타입(Type) 기능을 추가한 타입스크립트(TypeScript)가 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-01 오후 1.02.04.png&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;878&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bb64UJ/btsBgIPFoXY/GoL37P76Ux4k4GDaqhAkKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bb64UJ/btsBgIPFoXY/GoL37P76Ux4k4GDaqhAkKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bb64UJ/btsBgIPFoXY/GoL37P76Ux4k4GDaqhAkKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbb64UJ%2FbtsBgIPFoXY%2FGoL37P76Ux4k4GDaqhAkKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;365&quot; height=&quot;362&quot; data-filename=&quot;스크린샷 2023-12-01 오후 1.02.04.png&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;878&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;타입스크립트(TypeScript)란?&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;타입스크립트는 마이크로소프트가 개발하고 유지하고 있는 오픈소스 프로그래밍 언어로써 2012년에 처음 발표되었습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;타입이 있는 자바스크립트라는 단어보다는 정적 타입 시스템을 도입한 자바스크립트라는 뜻으로 프로그램의 예상 동작을 타입으로 나타내고, 그 예상에 맞게 동작할 지의 여부를 실행전에 확인이 가능합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 타입스크립트(TypeScript)는 프로그래밍 언어이면서 도구입니다. 코드를 실행하여 TypeScript코드를 JavaScript로 컴파일하여 새로운 기능으로써의 자바스크립트 코드를 얻을수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;타입스크립트(TypeScript)의 장점&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. 빠른 실행 속도&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트는 동적 타입의 프로그래밍 언어이기에 오류가 있는지 확인하는 작업으로 인하여 실행속도가 느리지만 타입스크립트(TypeScript)는 코드 작성을 할 때 타입을 미리 결정하기 때문에 런타임 때 작업을 줄어들어 실행속도가 빠른 장점이 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. 정적타입으로 인한 안정성 및 협업 용이성&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트 경우에는 코드를 작성시 타입을 짐작히기 어렵습니다. 어떠한 타입의 인수를 전달하여 어떠한 타입의 반환값을 Return을 해야하는지 명확하게 알 수 없습니다. 하지만 타입스크립트(TypeScript) 경우에는 정적 타입으로 인하여 코드의 가독성을 높이고 결과값을 정확하게 알 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3. 오류에 대한 디버깅 편이함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;타입스크립트 경우에는 타입을 부여하기에 코드 작성시 맞지 않는 타입을 넣거나, 타입을 넣지 않았을경우 IDE에서 오류라고 경고를 주게 됩니다. 이는 디버깅하는 시간을 줄여주기 때문에 생산적인 측면에서 아주 좋습니다.&lt;/p&gt;</description>
      <category>프로그래밍/Javascript</category>
      <category>JavaScript</category>
      <category>TypeScript</category>
      <category>자바스크립트</category>
      <category>타입스크립트</category>
      <category>타입스크립트장점</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/666</guid>
      <comments>https://redcow77.tistory.com/666#entry666comment</comments>
      <pubDate>Mon, 4 Dec 2023 18:22:52 +0900</pubDate>
    </item>
    <item>
      <title>[Python] Sys모듈로 파이썬 프로그램 종료하기</title>
      <link>https://redcow77.tistory.com/664</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-filename=&quot;python.PNG&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;277&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2Hf0M/btsk266J65w/toR5QxvMkHeqK6kyjz7Ktk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2Hf0M/btsk266J65w/toR5QxvMkHeqK6kyjz7Ktk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2Hf0M/btsk266J65w/toR5QxvMkHeqK6kyjz7Ktk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2Hf0M%2Fbtsk266J65w%2FtoR5QxvMkHeqK6kyjz7Ktk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;277&quot; data-filename=&quot;python.PNG&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;277&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;파이썬(Python)의 sys 모듈&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이썬(Python)의 sys 모듈은 파이썬의 인터프리터를 제어하는 모듈로써, 인터프리터에 의해 사용되거나 유지되는 변수와 함수에 대해서 액세스를 제공합니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특히 파이썬(Python) 프로젝트의 입력을 받는 argument를 관리하거나 platform에 따라서 처리해야되는것들, 그리고 파이썬(Python)의 버전, 프로그램 종료등의 시스템 관련된 정보나 제어를 할 수 있는 기능을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1687487138145&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys

# 파이썬의 현재버전 정보
print(sys.version)

# 파이썬의 모듈이 저장되어 있는 위치
print(sys.path)

# 인수전달하기 (인자전체)
print(sys.argv)

# platform 확인하기
print(sys.platform)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;파이썬(Python) 프로그램 종료하기&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이썬(Python)의 sys 모듈의 exit()를 이용하여 현재 실행되고 있는 파이썬 프로그램을 종료할수있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1687490048333&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys

print('python start!!')

sys.exit('END')

#실행되지 않음
print('python 실행확인!')&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/Python</category>
      <category>exit()</category>
      <category>Python</category>
      <category>SYS</category>
      <category>인터프리터</category>
      <category>파이썬</category>
      <category>파이썬모듈</category>
      <category>프로그램종료</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/664</guid>
      <comments>https://redcow77.tistory.com/664#entry664comment</comments>
      <pubDate>Fri, 23 Jun 2023 12:15:14 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 파이썬 설정한 시간에 따른 자동실행 - schedule 패키지</title>
      <link>https://redcow77.tistory.com/663</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;277&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ze0g5/btskSqlqKan/3cmzvjMXXh4EZ7gTX6Xu30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ze0g5/btskSqlqKan/3cmzvjMXXh4EZ7gTX6Xu30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ze0g5/btskSqlqKan/3cmzvjMXXh4EZ7gTX6Xu30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fze0g5%2FbtskSqlqKan%2F3cmzvjMXXh4EZ7gTX6Xu30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;277&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;277&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;파이썬(Python)의 schedule 패키지&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이썬(Python)의 schedule 패키지는 설정한 시간에 다라서 파이썬 스크립트가 자동실행 시키는 작업 라이브러리입니다. 이는 초, 분, 시간, 요일 등마다 실행이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1687411186213&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#schedule 라이브러리 설치
~/python &amp;gt; pip install schedule  
Collecting schedule
  Downloading schedule-1.2.0-py2.py3-none-any.whl (11 kB)
Installing collected packages: schedule
Successfully installed schedule-1.2.0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;schedule 패키지는 파이썬 내장 라이브러리인 time 모듈과 함께 사용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1687411634247&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import schedule
import time

# 10초에 한번씩 함수 실행
schedule.every(10).seconds.do(실행함수)

# 10분에 한번씩 함수 실행
schedule.every(10).minutes.do(실행함수)

# 10시간에 한번씩 함수 실행
schedule.every(10).hour.do(실행함수)

# 10일에 한번씩 함수 실행
schedule.every(10).days.do(실행함수)

# 일주일에 한번씩 함수 실행
schedule.every(1).weeks.do(실행함수)

# 매일 12시00분00초에 함수 실행
schedule.every().day.at(&quot;12:00:00&quot;).do(실행함수)

# 매주 일요일 12시00분00초에 함수 실행
#(monday, tuesday, wednesday, thursday, friday, saturday, sunday) - 소문자로 입력
schedule.every().sunday.at(&quot;12:00:00&quot;).do(실행함수)&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/Python</category>
      <category>Python</category>
      <category>Schedule</category>
      <category>TIME</category>
      <category>스케쥴</category>
      <category>파이썬</category>
      <category>파이썬자동실행</category>
      <category>패키지</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/663</guid>
      <comments>https://redcow77.tistory.com/663#entry663comment</comments>
      <pubDate>Thu, 22 Jun 2023 14:31:13 +0900</pubDate>
    </item>
    <item>
      <title>[Node.js] npm 패키지</title>
      <link>https://redcow77.tistory.com/662</link>
      <description>&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;npm 패키지란?&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm이란 Node.js 패키지 관리자로 Node Package Manager의 약자입니다. Node.js를 설치하게 되면 자동으로 설치되며, npm은 자바스크립트 라이브러리를 설치하고 관리할 수 있는 패키지 매니저입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IT 개발자들이 npm명령어를 통하여 자바스크립트 라이브러리를 쉽게 다운로드하고 관리하며 사용할수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm 패키지는 프론트엔드 프로젝트에서 많이 사용되며, 특히 Vue.js, React.js 와 같은 자바스크립트 프레임워크를 사용할 때에 npm으로 프로젝트의 버전을 쉽게 관리할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js 다운로드 : &lt;a href=&quot;https://nodejs.org/ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nodejs.org/ko&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1687313615367&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Node.js&quot; data-og-description=&quot;Node.js&amp;reg; is a JavaScript runtime built on Chrome's V8 JavaScript engine.&quot; data-og-host=&quot;nodejs.org&quot; data-og-source-url=&quot;https://nodejs.org/ko&quot; data-og-url=&quot;https://nodejs.org/ko&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c7aYul/hyS4pLNt2D/7aOu2FGNdKXn3KVvMvb1a1/img.png?width=224&amp;amp;height=256&amp;amp;face=0_0_224_256&quot;&gt;&lt;a href=&quot;https://nodejs.org/ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://nodejs.org/ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c7aYul/hyS4pLNt2D/7aOu2FGNdKXn3KVvMvb1a1/img.png?width=224&amp;amp;height=256&amp;amp;face=0_0_224_256');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Node.js&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Node.js&amp;reg; is a JavaScript runtime built on Chrome's V8 JavaScript engine.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;nodejs.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;npm 사용하기&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;npm을 사용하려면 npm이 정상적으로 설치되어 있는지 확인이 필요합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1687318505486&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#node.js 버전확인
&amp;gt; node -v

#npm 버전확인
&amp;gt;npm -v&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 npm을 사용하려면 초기설정이 필요한데 npm init 명령어를 실행하게 되면 초기설정을 하게 되며 package.json 파일을 생성하게 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그후에 npm 패키지를 설지 하면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1687318850076&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#npm 패키지 설치
$ npm install [패키지]

#npm 패키지 제거
$ npm uninstall [패키지]

#npm 패키지 전역 설치
$ npm install [패키지] --global&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패키지 최초 설치시에는 node_modules 폴더가 생성되며 그 하위폴더에 패키지 폴더 생성되어 설치됩니다. 설치된 패키지 버전 관리는 npm 초기설정 시 생성되었던 package.json 파일의 Dependencies 항목에서 확인이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;npm 명령어&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;npm에서 사용되는 명령어 목록을 확인하고 싶다면 npm만 입력하여 확인이 가능합니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1687319069488&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ npm

npm &amp;lt;command&amp;gt;

Usage:

npm install        install all the dependencies in your project
npm install &amp;lt;foo&amp;gt;  add the &amp;lt;foo&amp;gt; dependency to your project
npm test           run this project's tests
npm run &amp;lt;foo&amp;gt;      run the script named &amp;lt;foo&amp;gt;
npm &amp;lt;command&amp;gt; -h   quick help on &amp;lt;command&amp;gt;
npm -l             display usage info for all commands
npm help &amp;lt;term&amp;gt;    search for help on &amp;lt;term&amp;gt;
npm help npm       more involved overview

All commands:

    access, adduser, audit, bugs, cache, ci, completion,
    config, dedupe, deprecate, diff, dist-tag, docs, doctor,
    edit, exec, explain, explore, find-dupes, fund, get, help,
    hook, init, install, install-ci-test, install-test, link,
    ll, login, logout, ls, org, outdated, owner, pack, ping,
    pkg, prefix, profile, prune, publish, query, rebuild, repo,
    restart, root, run-script, search, set, shrinkwrap, star,
    stars, start, stop, team, test, token, uninstall, unpublish,
    unstar, update, version, view, whoami

Specify configs in the ini-formatted file:
    /Users/.npmrc
or on the command line via: npm &amp;lt;command&amp;gt; --key=value

More configuration info: npm help config
Configuration fields: npm help 7 config

npm@9.2.0 /Users/.nvm/versions/node/v19.3.0/lib/node_modules/npm&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;devDependencies 란 무엇인가?&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;npm 설치시 라이브러리가 배포용(dependencies)과 개발용(devDependencies)으로 구분되어야 합니다. 그 이유는 웹개발 배포 시 필요 없는 패키지를 빌드(build) 하지 않으므로써, 시간단축과 함께 리소스 관리에 도움이 되기 때문입니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 48.9535%; height: 161px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;패키지명&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;패키지 설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;webpack&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;빌드 도구&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;eslint&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;코드 문법 검사&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;imagemin&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;이미지 압축&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;scss&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;CSS 전처리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre id=&quot;code_1687319578859&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#devDependencies 설치

$ npm install [패키지명] -D&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;devDependencies 설치된 패키지 버전관리는 package.json 파일의 devDependencies 항목에서 확인이 가능합니다.&lt;/p&gt;</description>
      <category>프로그래밍/Node.js</category>
      <category>Node</category>
      <category>node.js</category>
      <category>NPM</category>
      <category>노드</category>
      <category>자바스크립트</category>
      <category>패키지관리</category>
      <category>패키지매니저</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/662</guid>
      <comments>https://redcow77.tistory.com/662#entry662comment</comments>
      <pubDate>Wed, 21 Jun 2023 12:54:26 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 파이썬(Python)의 JSON 인코딩,디코딩</title>
      <link>https://redcow77.tistory.com/661</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKlJOY/btskBCfFCVa/WJJkiG3i7LzbhppruEkYUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKlJOY/btskBCfFCVa/WJJkiG3i7LzbhppruEkYUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKlJOY/btskBCfFCVa/WJJkiG3i7LzbhppruEkYUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKlJOY%2FbtskBCfFCVa%2FWJJkiG3i7LzbhppruEkYUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;290&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Javascript 문법에서 가장 영향을 많이 받은 데이터 표현방식으로 JSON(Javascript Object Object Notation)이 있습니다. JSON은 데이터를 교환하는 포맷형식으로 웹 브라우저와 웹 서버 사이에서 데이터를 교환하는 방식으로 많이 사용되고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;Python의 JSON 인코딩&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이썬(Python) 프로그래밍에서 Object 표현방식을 JSON 형태로 변경하는것을 JSON 인코딩(Encoding)이라고 합니다. JSON 인코딩을 하기 위해서는 JSON 라이브러리인 json을 먼저 import 하여 json 라이브러리 내의 dumps 함수를 사용하여 변환 가능합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인코딩(Encoding)을 하게 되면 Object 형식의 데이터를 하나의 데이터로 표현이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1687245688564&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 테스트용 Python Dictionary
TestData = {
    'id': 1111,
    'name1': '철수',
    'name2': '영희',
    'history': [
        {'date': '2023-06-19', 'week': 'Monday'},
        {'date': '2023-06-20', 'week': 'Tuesday'},
    ]
}

jsonData = json.dumps(TestData)

print(jsonData)
print(type(jsonData))&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1687245733576&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;
{&quot;id&quot;: 1111, &quot;name1&quot;: &quot;\ucca0\uc218&quot;, &quot;name2&quot;: &quot;\uc601\ud76c&quot;, &quot;history&quot;: [{&quot;date&quot;: &quot;2023-06-19&quot;, &quot;week&quot;: &quot;Monday&quot;}, {&quot;date&quot;: &quot;2023-06-20&quot;, &quot;week&quot;: &quot;Tuesday&quot;}]}
&amp;lt;class 'str'&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;Python의 JSON 디코딩&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSON 인코딩의 반대적인 형태 변경으로 JSON 문자열을 파이썬(Python) 타입으로 변경하는 것을 JSON 디코딩(Decoding)이라고 합니다. JSON 디코딩은 &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;json 라이브러리 내의 loads 함수를 사용하여 변환 가능합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1687246234033&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 테스트용 JSON Data
JsonData = '{&quot;id&quot;: 1111, &quot;name1&quot;: &quot;철수&quot;, &quot;name2&quot;: &quot;영희&quot;, &quot;history&quot;: [{&quot;date&quot;: &quot;2023-06-19&quot;, &quot;week&quot;: &quot;Monday&quot;},{&quot;date&quot;: &quot;2023-06-20&quot;, &quot;week&quot;: &quot;Tuesday&quot;}]}'

dictData = json.loads(JsonData)

print(dictData['name1'])
for h in dictData['history']:
    print(h['date'], h['week'])&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1687246247896&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;철수
2023-06-19 Monday
2023-06-20 Tuesday&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/Python</category>
      <category>Dumps</category>
      <category>JSON</category>
      <category>loads</category>
      <category>Python</category>
      <category>디코딩</category>
      <category>인코딩</category>
      <category>파이썬</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/661</guid>
      <comments>https://redcow77.tistory.com/661#entry661comment</comments>
      <pubDate>Tue, 20 Jun 2023 16:31:51 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 파이썬(Python)의 아나콘다(Anaconda)란?</title>
      <link>https://redcow77.tistory.com/660</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b41yG4/btsknN8LKeO/rNw6n5caBbMrqZYriHGgfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b41yG4/btsknN8LKeO/rNw6n5caBbMrqZYriHGgfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b41yG4/btsknN8LKeO/rNw6n5caBbMrqZYriHGgfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb41yG4%2FbtsknN8LKeO%2FrNw6n5caBbMrqZYriHGgfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;290&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;Anaconda(아나콘다)?&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Anaconda(아나콘다)는 과학 연구 및 머신러닝 분야에서 사용되는 파이썬(Python) 언어의 패키지 및 의존성 관리 배포를 편리하게 해주는 조건적인 오픈소스 라이브러리입니다. 머신러닝 분야에서도 데이터 분석에 사용되는 여러 패키지가 기본적으로 포함되어 있기에 파이썬 개발 세팅에 매우 간단하기로 유명합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 파이썬(Python) 가상 환경을 구축하는데 유용하게 사용되는 conda라는 패키지 관리자가 존재하여 가상환경을 쉽게 관리가 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;Anaconda(아나콘다) 다운로드&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Anaconda(아나콘다) 공식 홈페이지에서 다운로드 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;windows 및 MacOs, Linux 버전을 지원하며, 현재 Python 3.10 버전을 지원가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.anaconda.com/download&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.anaconda.com/download&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1687149565272&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Free Download | Anaconda&quot; data-og-description=&quot;Anaconda's open-source Distribution is the easiest way to perform Python/R data science and machine learning on a single machine.&quot; data-og-host=&quot;www.anaconda.com&quot; data-og-source-url=&quot;https://www.anaconda.com/download&quot; data-og-url=&quot;https://www.anaconda.com/download&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cmXqei/hyS2Bsawy2/KsTq1KcTuftAjiTlSnXKh0/img.jpg?width=1440&amp;amp;height=1100&amp;amp;face=0_0_1440_1100,https://scrap.kakaocdn.net/dn/brzF5N/hyS2wK9tBD/L6lndnKgkkDHpxLRZN2nDk/img.png?width=1024&amp;amp;height=954&amp;amp;face=0_0_1024_954&quot;&gt;&lt;a href=&quot;https://www.anaconda.com/download&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.anaconda.com/download&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cmXqei/hyS2Bsawy2/KsTq1KcTuftAjiTlSnXKh0/img.jpg?width=1440&amp;amp;height=1100&amp;amp;face=0_0_1440_1100,https://scrap.kakaocdn.net/dn/brzF5N/hyS2wK9tBD/L6lndnKgkkDHpxLRZN2nDk/img.png?width=1024&amp;amp;height=954&amp;amp;face=0_0_1024_954');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Free Download | Anaconda&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Anaconda's open-source Distribution is the easiest way to perform Python/R data science and machine learning on a single machine.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.anaconda.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;Anaconda(아나콘다) 가상환경&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1687150455562&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#가상환경 생성
conda create -n [가상환경이름] python=3.10 

#가상환경 실행
conda activate [가상환경이름] 

#가상환경 종료
conda deactivate&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Python</category>
      <category>Anaconda</category>
      <category>conda</category>
      <category>Python</category>
      <category>가상환경</category>
      <category>아나콘다</category>
      <category>파이썬</category>
      <category>패키지관리자</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/660</guid>
      <comments>https://redcow77.tistory.com/660#entry660comment</comments>
      <pubDate>Mon, 19 Jun 2023 13:57:14 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]AWS 자격증이 경력개발에 필요한 이유</title>
      <link>https://redcow77.tistory.com/659</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-origin-width=&quot;389&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bghnfa/btsj3VeEvbY/oddSs5EhndjNNjq1P87Ayk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bghnfa/btsj3VeEvbY/oddSs5EhndjNNjq1P87Ayk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bghnfa/btsj3VeEvbY/oddSs5EhndjNNjq1P87Ayk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbghnfa%2Fbtsj3VeEvbY%2FoddSs5EhndjNNjq1P87Ayk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;389&quot; height=&quot;310&quot; data-origin-width=&quot;389&quot; data-origin-height=&quot;310&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;AWS 공인자격증이란?&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AWS 공인 자격증은 아키텍쳐, 개발, 운영등 다양한 IT영역의 지식, 기술, 업무역량을 보유하였음을 증명하는 AWS가 발급하는 자격증으로 일반적인 Cloud 작업 역활에 필요한 경험과 특정 기술 분야에서 전문성의 기준이 됩니다. AWS 공인 자격증을 취득함으로 이러한 기준에 충적하였음을 증명이 가능한 자격증입니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;AWS 공인자격증 필요한이유&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;IT분야에서 Cloud 전문성을 인정받는 방법은 여러가지가 있는데 AWS 공인 자격증은 매우 유용한 수단으로 관련 역활 또는 관련된 기술 영역의 전문가자 제출하는 자격증 시험으로 Cloud 숙련된 실무자가 되기 위하여 요구되는 필수 스킬을 익히는데 도움이 될것으로 판단됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/AWS</category>
      <category>AWS</category>
      <category>cloud전문가</category>
      <category>공인자격증</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/659</guid>
      <comments>https://redcow77.tistory.com/659#entry659comment</comments>
      <pubDate>Thu, 15 Jun 2023 14:33:12 +0900</pubDate>
    </item>
    <item>
      <title>[Javascript] 날짜 라이브러리 - moment.js</title>
      <link>https://redcow77.tistory.com/658</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-filename=&quot;js.PNG&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vl9x4/btrX4kVnaEJ/AF9nwfME39tzJ8jOssU26K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vl9x4/btrX4kVnaEJ/AF9nwfME39tzJ8jOssU26K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vl9x4/btrX4kVnaEJ/AF9nwfME39tzJ8jOssU26K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvl9x4%2FbtrX4kVnaEJ%2FAF9nwfME39tzJ8jOssU26K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;420&quot; height=&quot;432&quot; data-filename=&quot;js.PNG&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;자바스크립트(Javascript)의 moment.js&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자바스크립트(Javascript)에서 가장 많이 사용되는 날짜 및 시간을 다루는 라이브러리입니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;date() 함수보다 직관적이고 일관성이 있는 라이브러리로 현재에는 개발이 중단된 라이브러리입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개발이 중단이 되었지만 가장 오래된 라이브러리로써 현재까지도 많이 사용되고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;moment.js 라이브러리 설치&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;pre id=&quot;code_1675405186083&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ npm install moment&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;span style=&quot;color: #000000;&quot;&gt;moment.js 라이브러리 사용방법&lt;/span&gt;&lt;/h1&gt;
&lt;pre id=&quot;code_1675405297386&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import moment from 'moment';

or

const moment = require('moment');&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;&lt;span style=&quot;color: #000000;&quot;&gt;moment.js 라이브러리 활용&lt;/span&gt;&lt;/h1&gt;
&lt;pre id=&quot;code_1675405916808&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/** 현재 날짜 및 시간*/
let now = moment();
console.log(now.format());
// 2023-02-03T00:16:13+09:00

/** 날짜 및 시간 형식 포맷 */
console.log(now.format(&quot;YY-MM-DD&quot;));	// 23-02-03
console.log(now.format(&quot;DD/MM/YY&quot;));	// 03/02/23

/** 날짜 및 시간 검증(형식) */
console.log(moment(&quot;2023-02-03&quot;, &quot;YYYY-MM-DD&quot;).isValid()));	//true
console.log(moment(&quot;2023-02-03&quot;, &quot;DD/MM/YY&quot;).isValid()));	//false&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;&lt;span style=&quot;color: #000000;&quot;&gt;moment.js 라이브러리의 substract() 함수&lt;/span&gt;&lt;/h1&gt;
&lt;pre id=&quot;code_1675656587389&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* moment 객체에서 빼야할 값을 입력 *//
let now = moment();
now.subtract(1, 's').format('YYYY-MM-DD hh:mm:ss');	//현재시간에서 1초전
now.subtract(1, 'm').format('YYYY-MM-DD hh:mm:ss');	//현재시간에서 1분전
now.subtract(1, 'h').format('YYYY-MM-DD hh:mm:ss');	//현재시간에서 1시간전
now.subtract(1, 'd').format('YYYY-MM-DD');		//현재시간에서 1일전
now.subtract(1, 'month').format('YYYY-MM-DD');		//현재시간에서 한달전
now.subtract(1, 'y').format('YYYY-MM-DD');		//현재시간에서 1년전&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&lt;span style=&quot;color: #000000;&quot;&gt;moment.js 라이브러리의 add() 함수&lt;/span&gt;&lt;/h1&gt;
&lt;pre id=&quot;code_1675656801217&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* moment 객체에서 더해야할 값을 입력 *//
let now = moment();
now.add(1, 's').format('YYYY-MM-DD hh:mm:ss');	//현재시간에서 1초후
now.add(1, 'm').format('YYYY-MM-DD hh:mm:ss');	//현재시간에서 1분후
now.add(1, 'h').format('YYYY-MM-DD hh:mm:ss');	//현재시간에서 1시간후
now.add(1, 'd').format('YYYY-MM-DD');		//현재시간에서 1일후
now.add(1, 'month').format('YYYY-MM-DD');	//현재시간에서 한달후
now.add(1, 'y').format('YYYY-MM-DD');		//현재시간에서 1년후&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;&lt;span style=&quot;color: #000000;&quot;&gt;moment.js 라이브러리의 diff() 함수&lt;/span&gt;&lt;/h1&gt;
&lt;pre id=&quot;code_1675657202935&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 시간 또는 날짜 차이 계산 *//
let now = moment();
now.diff('2023-02-03', 'day');	//현재와 2023-02-03 날짜 차이

now.diff('2023-02-03 05:23:22', 's');	//현재와 2023-02-03 05:23:22와 초 차이

now.diff('2023-02-04 08:53:22', 'm');	//현재와 2023-02-04 08:53:22와 분 차이

now.diff('2023-02-02 11:03:22', 'h');	//현재와 2023-02-04 08:53:22와 시 차이

now.diff('2023-02-01', 'd');	//현재와 2023-02-01와 날짜 차이&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/Javascript</category>
      <category>diff()</category>
      <category>JavaScript</category>
      <category>Moment</category>
      <category>moment.js</category>
      <category>날짜</category>
      <category>라이브러리</category>
      <category>시간</category>
      <category>자바스크립트라이브러리</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/658</guid>
      <comments>https://redcow77.tistory.com/658#entry658comment</comments>
      <pubDate>Mon, 6 Feb 2023 13:21:21 +0900</pubDate>
    </item>
    <item>
      <title>프론트 개발 Mock Data 활용</title>
      <link>https://redcow77.tistory.com/657</link>
      <description>&lt;h1&gt;Mocking 활용&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 개발 프로젝트 진행시 백엔드 개발 완료 하기전에 프론트에서 Mock Data를 생성하여 프론트엔드 개발을 진행하도록 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;활용시 장점으로는 백엔드 API 개발 진행하기 전에 데이터의 형식 및 연동규격서를 공유하게 되면 웹 개발 프로젝트 진행시&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트엔드 개발과 백엔드 개발 병행이 가능&lt;/p&gt;
&lt;h1&gt;Mock Data란?&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mock Data란 실제 API에서 받아오는 데이터가 아닌 프론트엔드 개발자의 필요로 의해서 샘플로 만든 샘플데이터&lt;/p&gt;
&lt;h1&gt;기존 Mocking 방법&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트엔드에서 필요한 Mock Data를 내부 로직에서 저장하고 직접 Mocking하여 필요한 화면에서 붙이는 방식을 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이러한 방식은 구현이 쉽고 빠르게 적용이 가능하지만 서비스 로직에서 직접 Mocking 하는 방식으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스를 적용하기전에 서비스 로직을 수정하여 반영해야 하는 불편함이 있음 (불필요한 코드를 삭제 확인)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;public 폴더&amp;gt; data 폴더에 json의 Mock Data를 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 로직에서 fetch() 함수를 사용하여 API 주소와 가져올 방식으로 호출하여 then() 함수에서 Response 데이터를 설정가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch&quot;&gt;https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;MSW(Mock Service Worker) 라이브러리를 이용한 Mocking 방법&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSW는 서비스 워커(Service Worker)를 사용하여 네트워크 요청을 가로채서 Mock Data를 보내주는 Mocking Library&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mock 서버를 따로 구축하지 않고 API를 Mocking 가능함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장점으로는 웹 어플리케이션의 서비스 로직에 Mocking 코드가 필요없으며 백엔드 API 개발이 완료되면 MSW의 handler만 삭제하면 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mswjs.io/&quot;&gt;https://mswjs.io/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Service Worker란?&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 어플리케이션의 메인 스레드와 별도로 분리되어 백그라운드 스레드에서 실행가능한 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IE와 같은 일부의 브라우저에서는 지원되지 않으며 로컬 환경이 아니라면 HTTS 보안 프로토콜 환경이 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;MSW 라이브러리 설치 (react 기반)&lt;/h1&gt;
&lt;pre id=&quot;code_1674785579971&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ npm install msw --save-dev
or
$ yarn add msw --dev&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Servcie Worker 코드 생성&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;src폴더에 mocks폴더를 생성하고 browser.js파일을 생성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1674785595102&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ mkdir src/mocks
$ touch src/mocks/browser.js&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;browser.js 파일에 코드 작성&lt;/p&gt;
&lt;pre id=&quot;code_1674785609720&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/** src/mocks/browser.js */
import { setupWorker } from 'msw'
import { handlers } from './handlers'

/** This configures a Service Worker with the given request handlers. */
export const worker = setupWorker(...handlers)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;public 폴더에 Service Worker를 위한 JS 생성&lt;/p&gt;
&lt;pre id=&quot;code_1674785624414&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ npx msw init public/ --save&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;public 폴더에 mockServcieWorker.js 파일 생성되며 package.json에 워킹 디렉토리 추가됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;index.js파일에 MSW 설정추가&lt;/h1&gt;
&lt;pre id=&quot;code_1674785639556&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/** src/index.js */
import React from 'react';
import ReactDOM from 'react-dom';

import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

/** 개발환경이 development 경우에 mocks 폴더에 worker를 실행 (일반 API호출할 경우 주석처리) */
if (process.env.NODE_ENV === 'development') {
  const { worker } = require('./mocks/browser')
  worker.start()
}

ReactDOM.render(&amp;lt;App /&amp;gt;, document.getElementById('root'));

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Etc</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/657</guid>
      <comments>https://redcow77.tistory.com/657#entry657comment</comments>
      <pubDate>Fri, 27 Jan 2023 11:15:04 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 파이썬(Python)의 가변인자, 키워드가변인자</title>
      <link>https://redcow77.tistory.com/656</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kB1pV/btrK6Ao5Tid/VziEreOkSyQPmPtb4luwlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kB1pV/btrK6Ao5Tid/VziEreOkSyQPmPtb4luwlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kB1pV/btrK6Ao5Tid/VziEreOkSyQPmPtb4luwlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkB1pV%2FbtrK6Ao5Tid%2FVziEreOkSyQPmPtb4luwlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;290&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Python(파이썬)의 가변인자(*args)란 임의의 개수의 인자를 받는 함수를 말하며 Arguments의 줄임말입니다.&amp;nbsp; 함수를 구현할때 선언한 매개변수의 개수에 맞추어 파라미터를 넘겨주어야 하는데 임의 개수의 파라미터를 받을때에 * 기호를 붙히게 되면 여러개의 파라미터를 붙일수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;Python(파이썬) 가변인자(*args)&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Python(파이썬)의 가변인자 함수는 함수의 매개변수 숫자를 알지 못할때 사용하는 방식으로써 함수의 매개변수 앞에 *를 한개 붙여주게 되면 함수의 매개 변수를 몇개를 입력하든 함수 내에서 튜플로 인식하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;Python(파이썬) 키워드가변인자(**kwargs)&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Python(파이썬)의 키워드가변인자는 임의의 개수의 키워드인자도 받을수 있는데 매개변수 앞에 **를 붙여서 사용하게 됩니다. 키워드 인자로 전달하면 함수 내에서 딕셔너리로 인식하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1662012603238&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#가변인자
def def_args(*num):
	print(num)
    
def_args(1,2,3,4,5)


===================
1
2
3
4
5


#키워드가변인자
def def_kwargs(x, y, **data):
    #x -&amp;gt; 1
    #y -&amp;gt; 100
    #data - &amp;gt; {name= &quot;redcow7&quot;, age = 99, skill = &quot;Python&quot;}
    
    
def_kwargs(1, 100, name= &quot;redcow7&quot;, age = 99, skill = &quot;Python&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Python</category>
      <category>args</category>
      <category>kwargs</category>
      <category>Python</category>
      <category>가변인자</category>
      <category>딕셔너리</category>
      <category>키워드가변인자</category>
      <category>튜플</category>
      <category>파이썬</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/656</guid>
      <comments>https://redcow77.tistory.com/656#entry656comment</comments>
      <pubDate>Thu, 1 Sep 2022 15:11:44 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 파이썬(Python) 리스트 정렬 함수 - sort(), reverse() 함수</title>
      <link>https://redcow77.tistory.com/655</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bx5OfI/btrK3YiymeG/DC4B6wDm1PXg7mggkXu5E0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bx5OfI/btrK3YiymeG/DC4B6wDm1PXg7mggkXu5E0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bx5OfI/btrK3YiymeG/DC4B6wDm1PXg7mggkXu5E0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbx5OfI%2FbtrK3YiymeG%2FDC4B6wDm1PXg7mggkXu5E0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;290&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Python(파이썬)에서 리스트 형태의 Data를 정렬하는 함수가 있습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;Python(파이썬) sort 함수&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Python(파이썬)의 sort 함수는 LIST 객체를 정렬해주는 함수입니다. LIST 객체에서만 사용이 가능합니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;기본적으로 LIST 객체를 오름차순으로 정렬하여주는 기능을 합니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;내림차순으로 정렬하는 방법은 sort() 함수의 옵션인 reverse 인자의 값을 True로 설정하게 되면 내림차순으로 정렬하게 됩니다. reverse() 함수와는 다릅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;Python(파이썬) reverse() 함수&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Python(파이썬)의 reverse() 함수는 LIST 객체를 뒤집는 함수입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;Python(파이썬) clear() 함수&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Python(파이썬)의 clear() 함수는 LIST 객체를 모두 삭제하는&amp;nbsp; 함수입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1661924276332&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;list_num = [21, 2, 50, 44, 3, 0, 99, 5]

#뒤집기 정렬
print(&quot;#뒤집기 정렬&quot;)
list_num.reverse()
print(list_num)

#올림차순 정렬
print(&quot;#올림차순 정렬&quot;)
list_num.sort()
print(list_num)

#내림차순 정렬
print(&quot;#내림차순 정렬&quot;)
list_num.sort(reverse=True)
print(list_num)

#모두 지우기
print(&quot;#모두 지우기&quot;)
list_num.clear()
print(list_num)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Python</category>
      <category>clear</category>
      <category>Python</category>
      <category>Reverse</category>
      <category>sort</category>
      <category>내림차순</category>
      <category>올림차순</category>
      <category>정렬</category>
      <category>파이썬</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/655</guid>
      <comments>https://redcow77.tistory.com/655#entry655comment</comments>
      <pubDate>Wed, 31 Aug 2022 14:39:28 +0900</pubDate>
    </item>
    <item>
      <title>[React] react.js의 HTML &amp;lt;a&amp;gt; 태그 관련 에러</title>
      <link>https://redcow77.tistory.com/654</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k6n7f/btrGupznu4U/wchNxjwEH9ukpa9GKfiTS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k6n7f/btrGupznu4U/wchNxjwEH9ukpa9GKfiTS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k6n7f/btrGupznu4U/wchNxjwEH9ukpa9GKfiTS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk6n7f%2FbtrGupznu4U%2FwchNxjwEH9ukpa9GKfiTS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;react.js의 HTML &amp;lt;a&amp;gt; 태그 관련 Error 발생&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The&amp;nbsp;href&amp;nbsp;attribute&amp;nbsp;requires&amp;nbsp;a&amp;nbsp;valid&amp;nbsp;value&amp;nbsp;to&amp;nbsp;be&amp;nbsp;accessible.&amp;nbsp;Provide&amp;nbsp;a&amp;nbsp;valid,&amp;nbsp;navigable&amp;nbsp;address&amp;nbsp;as&amp;nbsp;the&amp;nbsp;href&amp;nbsp;value.&amp;nbsp;If&amp;nbsp;you&amp;nbsp;cannot&amp;nbsp;provide&amp;nbsp;a&amp;nbsp;valid&amp;nbsp;href,&amp;nbsp;but&amp;nbsp;still&amp;nbsp;need&amp;nbsp;the&amp;nbsp;element&amp;nbsp;to&amp;nbsp;resemble&amp;nbsp;a&amp;nbsp;link,&amp;nbsp;use&amp;nbsp;a&amp;nbsp;button&amp;nbsp;and&amp;nbsp;change&amp;nbsp;it&amp;nbsp;with&amp;nbsp;appropriate&amp;nbsp;styles.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1567&quot; data-origin-height=&quot;68&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/07B4x/btrGzuMdsPo/kNb8tyz8L5AidyAXihMiEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/07B4x/btrGzuMdsPo/kNb8tyz8L5AidyAXihMiEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/07B4x/btrGzuMdsPo/kNb8tyz8L5AidyAXihMiEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F07B4x%2FbtrGzuMdsPo%2FkNb8tyz8L5AidyAXihMiEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1567&quot; height=&quot;68&quot; data-origin-width=&quot;1567&quot; data-origin-height=&quot;68&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React에서 흔히 볼 수 있는 에러입니다. 이는 코드규칙을 관리할때 사용되는 라이브러리 eslint에서 제공되는 경고로써 react.js의 &amp;lt;a&amp;gt; 태그를 사용할 때에는 href의 유효성값이 필요하다는 Error입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1656997318303&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;The href attribute requires a valid value to be accessible.
Provide a valid, navigable address as the href value. 
If you cannot provide a valid href, but still need 
the element to resemble a link, use a button and change 
it with appropriate styles.&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1656997057376&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//잘못된 코드
&amp;lt;a href=&quot;#&quot;&amp;gt;Naver&amp;lt;/a&amp;gt;

//수정된 코드
&amp;lt;a href=&quot;#!&quot;&amp;gt;Naver&amp;lt;/a&amp;gt;
&amp;lt;a href=&quot;{()=&amp;gt;false}&quot;&amp;gt;Naver&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>a태그</category>
      <category>href</category>
      <category>react</category>
      <category>react.js</category>
      <category>warning</category>
      <category>리액트</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/654</guid>
      <comments>https://redcow77.tistory.com/654#entry654comment</comments>
      <pubDate>Wed, 6 Jul 2022 11:02:54 +0900</pubDate>
    </item>
    <item>
      <title>[React] react.js의 HTML img 태그 관련 에러</title>
      <link>https://redcow77.tistory.com/653</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9PT0m/btrGupzimUM/2GykLwTVSQ4CSxnJ8oSonk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9PT0m/btrGupzimUM/2GykLwTVSQ4CSxnJ8oSonk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9PT0m/btrGupzimUM/2GykLwTVSQ4CSxnJ8oSonk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9PT0m%2FbtrGupzimUM%2F2GykLwTVSQ4CSxnJ8oSonk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;react.js의 HTML img 태그 관련 Error 발생&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;img&amp;nbsp;elements&amp;nbsp;must&amp;nbsp;have&amp;nbsp;an&amp;nbsp;alt&amp;nbsp;prop,&amp;nbsp;either&amp;nbsp;with&amp;nbsp;meaningful&amp;nbsp;text,&amp;nbsp;or&amp;nbsp;an&amp;nbsp;empty&amp;nbsp;string&amp;nbsp;for&amp;nbsp;decorative&amp;nbsp;images&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;785&quot; data-origin-height=&quot;93&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBLd52/btrGs1ehBnQ/6Yc1lPvxZ48aet03MnuAL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBLd52/btrGs1ehBnQ/6Yc1lPvxZ48aet03MnuAL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBLd52/btrGs1ehBnQ/6Yc1lPvxZ48aet03MnuAL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBLd52%2FbtrGs1ehBnQ%2F6Yc1lPvxZ48aet03MnuAL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;785&quot; height=&quot;93&quot; data-origin-width=&quot;785&quot; data-origin-height=&quot;93&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React에서 흔히 볼 수 있는 에러입니다. 이는 코드규칙을 관리할때 사용되는 라이브러리 eslint에서 제공되는 경고로써 react.js의 img 태그를 사용할 때에는 alt를 작성하지 않았다는 Error입니다. 사실 alt를 작성하지 않아도 되지만 표준에 맞게 사용하려면 alt를 빼면 안 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1656996259984&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//잘못된 코드
&amp;lt;img src=&quot;./images/icon/android.jpg&quot; /&amp;gt;
&amp;lt;img src=&quot;./images/icon/ios.jpg&quot; /&amp;gt;


//수정된 코드
&amp;lt;img src=&quot;./images/icon/android.jpg&quot; alt=&quot;android&quot;/&amp;gt;
&amp;lt;img src=&quot;./images/icon/ios.jpg&quot; alt=&quot;ios&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>alt작성하세요</category>
      <category>img태그</category>
      <category>react</category>
      <category>react.js</category>
      <category>warning</category>
      <category>리액트</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/653</guid>
      <comments>https://redcow77.tistory.com/653#entry653comment</comments>
      <pubDate>Tue, 5 Jul 2022 13:49:43 +0900</pubDate>
    </item>
    <item>
      <title>[React] Invalid DOM property `for`. Did you mean `htmlFor`에러</title>
      <link>https://redcow77.tistory.com/652</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tBwFM/btrBTsUBk30/nmJdKBr7YxV8GKnowiqPz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tBwFM/btrBTsUBk30/nmJdKBr7YxV8GKnowiqPz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tBwFM/btrBTsUBk30/nmJdKBr7YxV8GKnowiqPz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtBwFM%2FbtrBTsUBk30%2FnmJdKBr7YxV8GKnowiqPz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;Invalid&amp;nbsp;DOM&amp;nbsp;property&amp;nbsp;`for`.&amp;nbsp;Did&amp;nbsp;you&amp;nbsp;mean&amp;nbsp;`htmlFor`&amp;nbsp;Error 발생&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Warning: Invalid&amp;nbsp;DOM&amp;nbsp;property&amp;nbsp;`for`.&amp;nbsp;Did&amp;nbsp;you&amp;nbsp;mean&amp;nbsp;`htmlFor`.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;353&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsztSj/btrBXu5kcq1/TBsLN9LFplcFPgRuvFL9r1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsztSj/btrBXu5kcq1/TBsLN9LFplcFPgRuvFL9r1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsztSj/btrBXu5kcq1/TBsLN9LFplcFPgRuvFL9r1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsztSj%2FbtrBXu5kcq1%2FTBsLN9LFplcFPgRuvFL9r1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1046&quot; height=&quot;353&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;353&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React에서 흔히 볼 수 있는 에러입니다. React의 JSX는 자바스크립트의 구조로 만들어져 있습니다. &amp;lt;label&amp;gt; 태그에서 for는 반복문을 인식하기에 발생되는 에러입니다. 따라서 JSX문법에 맞게 수정을 해야 합니다. JSX문법에 맞는 코드는 htmlFor입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1652337761878&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//잘못된 코드

&amp;lt;label for=&quot;&quot;&amp;gt;
    React Jsx 문법
&amp;lt;/label &amp;gt;


//수정된 코드
&amp;lt;label htmlFor=&quot;&quot;&amp;gt;
    React Jsx 문법
&amp;lt;/label &amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>label태그문법</category>
      <category>react</category>
      <category>react.js</category>
      <category>리액트</category>
      <category>리액트오류</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/652</guid>
      <comments>https://redcow77.tistory.com/652#entry652comment</comments>
      <pubDate>Thu, 12 May 2022 15:43:53 +0900</pubDate>
    </item>
    <item>
      <title>[React] Expected `onClick` listener to be a function, instead got `false`  에러</title>
      <link>https://redcow77.tistory.com/651</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cje3C0/btrBDmlOFp6/kPWCWMxG2uqm77mtnaJARK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cje3C0/btrBDmlOFp6/kPWCWMxG2uqm77mtnaJARK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cje3C0/btrBDmlOFp6/kPWCWMxG2uqm77mtnaJARK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcje3C0%2FbtrBDmlOFp6%2FkPWCWMxG2uqm77mtnaJARK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;Expected&amp;nbsp;`onClick`&amp;nbsp;listener&amp;nbsp;to&amp;nbsp;be&amp;nbsp;a&amp;nbsp;function,&amp;nbsp;instead&amp;nbsp;got&amp;nbsp;`false`&amp;nbsp;Error 발생&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Warning:&amp;nbsp;Expected&amp;nbsp;`onClick`&amp;nbsp;listener&amp;nbsp;to&amp;nbsp;be&amp;nbsp;a&amp;nbsp;function,&amp;nbsp;instead&amp;nbsp;got&amp;nbsp;`false`.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1045&quot; data-origin-height=&quot;292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nlk55/btrBx0qG4oZ/Vk0PZIXOfWRzljcIvMEsFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nlk55/btrBx0qG4oZ/Vk0PZIXOfWRzljcIvMEsFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nlk55/btrBx0qG4oZ/Vk0PZIXOfWRzljcIvMEsFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnlk55%2FbtrBx0qG4oZ%2FVk0PZIXOfWRzljcIvMEsFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1045&quot; height=&quot;292&quot; data-origin-width=&quot;1045&quot; data-origin-height=&quot;292&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React Component에서 Button 등과 같은 이벤트 발생 후에 특정한 함수인 function을 호출하려 할 때에 발생하는 Error입니다. 이는 정상적으로 호출은 되긴 하지만 React의 Console창에서 경고인 오류를 보이게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1652063498617&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//잘못된 코드
&amp;lt;button onClick={condition &amp;amp;&amp;amp; value}&amp;gt;
  Click
&amp;lt;/button&amp;gt;


//수정된 코드
&amp;lt;button onClick={condition ? value : undefined}&amp;gt;
  Click
&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>onclick오류</category>
      <category>react</category>
      <category>react.js</category>
      <category>리액트</category>
      <category>리액트오류</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/651</guid>
      <comments>https://redcow77.tistory.com/651#entry651comment</comments>
      <pubDate>Mon, 9 May 2022 11:33:05 +0900</pubDate>
    </item>
    <item>
      <title>[React] React.js 의 popup창에서 부모창의 함수 호출</title>
      <link>https://redcow77.tistory.com/650</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bs2ZMA/btrzMaBFuFO/VBCWvlCcjcwcuXuJ3LiCLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bs2ZMA/btrzMaBFuFO/VBCWvlCcjcwcuXuJ3LiCLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bs2ZMA/btrzMaBFuFO/VBCWvlCcjcwcuXuJ3LiCLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbs2ZMA%2FbtrzMaBFuFO%2FVBCWvlCcjcwcuXuJ3LiCLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React에서 팝업창으로 오픈하여 데이터를 처리한 후에 부모 창에 있는 함수를 호출하는 상황을 정리합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;부모 창에서 버튼을 클릭하였을 경우에 popup.jsp을 새창으로 열고 요소 내부에 기능의 함수를 설정합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1650343809186&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//부모창

export default function ParentFunc() {

  function popupFunction() {
    let popup = window.open(&quot;/popup.jsp&quot;, &quot;&quot;, 'width=800,height=600');

    window.parentCallback = () =&amp;gt; {
      console.log('Hello World!!');
    }
  }
  
   return (
    &amp;lt;div&amp;gt;
        &amp;lt;button variant=&quot;info&quot; type=&quot;submit&quot; onClick={someFunction}&amp;gt;
            popup button
        &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
   );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새창으로 popup.jsp을 열고 ParentFunc() 함수를 호출하였을 경우에 부모 창에 있는 설정되어 있는 parentCallblack() 함수를 호출하게 되면 console에 &quot;Hello World!!&quot;가 표시되게 되고 popup.jsp 창이 닫히게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1650343678406&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//팝업창 함수

export default function ParentFunc() {

    window.opener.parentCallback();
    window.close();

    return (
      &amp;lt;div className=&quot;content&quot;&amp;gt;
        &amp;lt;p&amp;gt;Parent Page&amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
    );
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>react</category>
      <category>reactjs</category>
      <category>리액트</category>
      <category>부모창함수호출</category>
      <category>팝업창</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/650</guid>
      <comments>https://redcow77.tistory.com/650#entry650comment</comments>
      <pubDate>Tue, 19 Apr 2022 13:58:15 +0900</pubDate>
    </item>
    <item>
      <title>[React] React.js 의 debounce 함수</title>
      <link>https://redcow77.tistory.com/649</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4EO1q/btrueeuyYyM/8jrbOkfbAGmgYnxFtLeQnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4EO1q/btrueeuyYyM/8jrbOkfbAGmgYnxFtLeQnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4EO1q/btrueeuyYyM/8jrbOkfbAGmgYnxFtLeQnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4EO1q%2FbtrueeuyYyM%2F8jrbOkfbAGmgYnxFtLeQnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이벤트 발생과 그에 따른 이벤트 핸들러 콜백 함수를 다루는 것은 프로그램 코드를 작성하는데 가장 중요한 개념입니다. 클릭이벤트처럼 단순하지 않으며 키보드의 입력이 지속적으로 발생할 경우 여러 번의 이벤트를 통하여 API를 호출하게 되면 서버에 과부하가 발생하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;debounce란?&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;debounce란 특정 이벤트가 발생할 때에 작동하는 비즈니스 로직이 과도하게 발생하는 것을 방지하기 위하여 사용되는 함수입니다. onchange() 함수를 통하여 이벤트가 발생할 때마다 서버에 API를 호출하기보다는 일정 시간이 지난 후에 서버 API를 호출하게 되는 지연 호출의 역할을 하는 함수를 말합니다. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수의 설정마다 다르겠지만 호출되는 함수들 중 마지막 또는 제일 처음만 호출하도록 하는 함수입니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비슷한 함수로는 throttle() 함수가 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1645614813659&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;input class=&quot;textInput&quot; /&amp;gt;

document.querySelector('.textInput').addEventListener('input', function(e) {
  console.log('이벤트 발생중', e.target.value);
});

//debounce 함수 역활 하는 코드
let timer;
document.querySelector('.textInput').addEventListener('input', function(e) {
  if (timer) {
    clearTimeout(timer);
  }
  timer = setTimeout(function() {
    console.log('마지막 이벤트 발생중', e.target.value);
  }, 200);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React에서는 lodash 라이브러리인 debounce 함수를 사용할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1645615040909&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;input type=&quot;text&quot; onChange={debounceFunction} /&amp;gt;


import React from &quot;react&quot;;
import { debounce } from &quot;lodash&quot;;

const debounceFunction = debounce(() =&amp;gt; {
  console.log(&quot;debounce 함수 호출중!&quot;);
}, 200);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>debounce 함수</category>
      <category>lodash라이브러리</category>
      <category>react</category>
      <category>settime()</category>
      <category>throttle</category>
      <category>리액트</category>
      <category>리액트지연호출</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/649</guid>
      <comments>https://redcow77.tistory.com/649#entry649comment</comments>
      <pubDate>Wed, 23 Feb 2022 20:18:56 +0900</pubDate>
    </item>
    <item>
      <title>[React] React.js 의 JSX 문법</title>
      <link>https://redcow77.tistory.com/648</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7RLYv/btrt3eB4LHd/BhByYAoKHD8yE1xOjX8u4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7RLYv/btrt3eB4LHd/BhByYAoKHD8yE1xOjX8u4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7RLYv/btrt3eB4LHd/BhByYAoKHD8yE1xOjX8u4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7RLYv%2Fbtrt3eB4LHd%2FBhByYAoKHD8yE1xOjX8u4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React에서는 HTML을 직접적으로 작성하지 않고 유사해 보이는 JSX을 사용합니다.&amp;nbsp; JSX란 자바스크립트의 확장된 문법으로써 XML과 비슷하게 생긴 프로그래밍 언어입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;React의 JSX란?&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;JSX란 자바스크립트의 확장된 문법으로써 Javascript XML의 줄임말입니다. JSX는 React에서 사용되는 문법으로 공식적인 자바스크립트 문법은 아닙니다. 브라우저에서 실행하기 전에 바벨을 사용하여 일반 자바스크립트 형태의 문법으로 변환됩니다. 바벨에서는 여러 문법을 지원할 수 있도록 preset 및 plugin을 설정하여 개발자들이 임의로 만든 문법 또는 자바스크립트의 문법을 사용할 수 있도록 변환합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;JSX 문법 규칙&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 부모의 요소 하나가 반드시 감싸는 형태야 하는 규칙&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;- Virtual DOM에서 컴포넌트 변화를 감지하여 효율적으로 비교할 수 있도록 컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 자바스크립트 표현식&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- JSX 문법 내부에 있는 코드를 { }로 감싸게 되면 자바스크립트 표현식을 사용 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 조건부 연산자 및 조건부 렌더링&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- JSX 내부에서 자바스크립트 표현식을 사용할 때에는 조건문을 사용할 수 없지만 조건에 따라서 다른 내용을 렌더링을 할 때에는 삼항 연산자를 통하여 조건부 연산자를 사용할 수 있습니다. 또한 AND연산자(&amp;amp;&amp;amp;)를 사용하면 더 짧은 코드로 조건부 렌더링을 사용 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 주석처리 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- JSX 문법에서 주석처리 방법으로는 {/*.....*/}와 같은 방법을 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. JSX 문법에서의 class 사용방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- JSX 문법에서는 class가 아닌 className으로 사용해야만 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. JSX 문법에서의 undefined 반환 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- React 컴포넌트의 함수에서 undefined를 반환하여 렌더링을 하지 않을 때에는 OR(||) 연산자를 사용하여 오류를 방지해야만 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>JSX문법</category>
      <category>JSX오류방지</category>
      <category>react</category>
      <category>리액트</category>
      <category>리액트JSX오류</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/648</guid>
      <comments>https://redcow77.tistory.com/648#entry648comment</comments>
      <pubDate>Tue, 22 Feb 2022 15:44:58 +0900</pubDate>
    </item>
    <item>
      <title>[React] Each child in a list should have a unique &amp;quot;key&amp;quot;  에러</title>
      <link>https://redcow77.tistory.com/647</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbcnFN/btrtwqdbJkL/MGAIyXzmnrAsTL2QlDw5K0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbcnFN/btrtwqdbJkL/MGAIyXzmnrAsTL2QlDw5K0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbcnFN/btrtwqdbJkL/MGAIyXzmnrAsTL2QlDw5K0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbcnFN%2FbtrtwqdbJkL%2FMGAIyXzmnrAsTL2QlDw5K0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;Each child in a list should have a unique &quot;key&quot; Error 발생&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Warning: Each child in a list should have a unique &quot;key&quot; prop.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;826&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KGzbm/btrtBOQ8f1a/00vJXBKsR4Hw30rUWtninK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KGzbm/btrtBOQ8f1a/00vJXBKsR4Hw30rUWtninK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KGzbm/btrtBOQ8f1a/00vJXBKsR4Hw30rUWtninK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKGzbm%2FbtrtBOQ8f1a%2F00vJXBKsR4Hw30rUWtninK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;826&quot; height=&quot;252&quot; data-origin-width=&quot;826&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React 프로젝트를 진행 중에 발생하는 Error입니다. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이는 Chrome의 개발자 도구인 Console에서 확인할 수 있으며 React에서 map 함수를 사용하여 반복문을 사용하는 경우에 발생하는 스크립트 오류입니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React에서는 key prop를 사용하여 컴포넌트와 DOM 요소 간의 관계를 생성합니다. React 라이브러리는 이 관계를 이용하여 컴포넌트 렌더링 여부를 결정하기 때문에 불필요한 렌더링을 방지하기 위하여 각 자식 컴포넌트마다 독립적인 Key 값을 넣어줘야 하는데 Key 값이 없는 경우에 발생하는 오류입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React의 JSX에서 배열로 map함수를 사용하여 리스트를 생성할때 key prop를 자식 컴포넌트마다 넣어줘야 오류를 해결할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 조심해야하는 경우에는 key값이 Root 컴포넌트에 적용되어야 하는데 Fragment부분이 Root로 map처리되는 경우에도 에러가 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1645079034237&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//잘못된 코드
{ list.map((item)=&amp;gt;(
     &amp;lt;&amp;gt;
       &amp;lt;div key={item}&amp;gt; Component &amp;lt;/div&amp;gt;
     &amp;lt;/&amp;gt;
  ))
}

//수정된 코드
{ list.map((item)=&amp;gt;(
	&amp;lt;div key={item}&amp;gt; Component &amp;lt;/div&amp;gt;
  ))
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>key prop</category>
      <category>key에러</category>
      <category>react</category>
      <category>reactjs</category>
      <category>리액트</category>
      <category>리액트에러</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/647</guid>
      <comments>https://redcow77.tistory.com/647#entry647comment</comments>
      <pubDate>Thu, 17 Feb 2022 15:25:17 +0900</pubDate>
    </item>
    <item>
      <title>[React] &amp;lt;input&amp;gt; cannot appear as a child of &amp;lt;table&amp;gt;. 에러</title>
      <link>https://redcow77.tistory.com/646</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5TuMb/btrtlsItsJZ/Bnk2AwoBBkt1qCf7uxpZw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5TuMb/btrtlsItsJZ/Bnk2AwoBBkt1qCf7uxpZw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5TuMb/btrtlsItsJZ/Bnk2AwoBBkt1qCf7uxpZw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5TuMb%2FbtrtlsItsJZ%2FBnk2AwoBBkt1qCf7uxpZw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;&amp;lt;input&amp;gt;&amp;nbsp;cannot&amp;nbsp;appear&amp;nbsp;as&amp;nbsp;a&amp;nbsp;child&amp;nbsp;of&amp;nbsp;&amp;lt;table&amp;gt;.&amp;nbsp;Error 발생&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Warning:&amp;nbsp;validateDOMNesting(...):&amp;nbsp;&amp;lt;input&amp;gt;&amp;nbsp;cannot&amp;nbsp;appear&amp;nbsp;as&amp;nbsp;a&amp;nbsp;child&amp;nbsp;of&amp;nbsp;&amp;lt;table&amp;gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;291&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dNE6X3/btrtmgnvPo9/rugSxxVkBO10MJA9KdDJQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dNE6X3/btrtmgnvPo9/rugSxxVkBO10MJA9KdDJQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dNE6X3/btrtmgnvPo9/rugSxxVkBO10MJA9KdDJQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdNE6X3%2FbtrtmgnvPo9%2FrugSxxVkBO10MJA9KdDJQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;978&quot; height=&quot;291&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;291&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React 프로젝트를 진행 중에 발생하는 Error입니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이는 Chrome의 개발자 도구인 Console에서 확인할 수 있는 Error로써 스크립트 오류로 확인할 수 있습니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이는 &amp;lt;table&amp;gt; 태그 안에 &amp;lt;input&amp;gt; 태그가 들어가면 안 된다는 스크립트 오류입니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(&amp;lt;table&amp;gt; 자식으로 &amp;lt;input&amp;gt;가 올수 없다는 경고)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 React의 JSX에서 Table를 쓸때에는 유의해야 할 부분이 있습니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React의 JSX 사용시 반드시 tbody와 thead를 써야 하며 tbody를 선언해야만 tr과 td를 사용할 수 있습니다. 그리고 thead를 작성해야만 th를 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;따라서 React에서 table를 올바르게 사용하려면 thead와 tbody를 잘 선언해야 하며 속성 안에는 다른 태그를 넣어서는 안 됩니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>JSX문법</category>
      <category>JSX문법오류</category>
      <category>react</category>
      <category>React Table</category>
      <category>리액트JSX문법</category>
      <category>리액트오류</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/646</guid>
      <comments>https://redcow77.tistory.com/646#entry646comment</comments>
      <pubDate>Tue, 15 Feb 2022 17:28:35 +0900</pubDate>
    </item>
    <item>
      <title>[React] React.js 조건문 - IF 문</title>
      <link>https://redcow77.tistory.com/645</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hezis/btrtak4Th6o/IEKYfpW680XFFm80ze60B0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hezis/btrtak4Th6o/IEKYfpW680XFFm80ze60B0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hezis/btrtak4Th6o/IEKYfpW680XFFm80ze60B0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHezis%2Fbtrtak4Th6o%2FIEKYfpW680XFFm80ze60B0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React를 개발 시 JSX 또는 일반 코드 작성 시에 조건문인 IF/ELSE를 사용하는 경우가 있습니다. React에서는 컴포넌트에 render 함수가 필요하며 JSX로 Return을 해줘야 하기에 IF문 또는 Switch문 사용이 제한이 있습니다. 그렇기에 삼항 연산자 또는 &amp;amp;&amp;amp;연산자를 많이 사용하게 됩니다. React에서는 IF 조건문을 어떻게 사용하는지 알아보도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;React IF/ELSE 문&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React에서 IF/ELSE문을 사용하려면 컴포넌트에서 JSX를 조건에 따라서 작성해야만 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644804708152&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function Component() {
  if ( true ) {
    return &amp;lt;p&amp;gt;Component True&amp;lt;/p&amp;gt;;
  } else {
    return null;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;React 삼항연산자&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;삼항 연산자란 React의 JSX에서 주로 사용되는 언어입니다. 삼항 연산자는 중첩 사용도 가능합니다. 하지만 단점으로는 익숙하지 않은 코드로 인하여 불편할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644804990520&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//삼항연잔자 문법
조건 ? [조건이 참인경우 코드] : [조건이 거짓인경우 코드]


function Component() {
  return (
    &amp;lt;div&amp;gt;
      {
        2 === 1
        ? &amp;lt;p&amp;gt;Component 첫번째 조건 True.&amp;lt;/p&amp;gt;
        : ( 2 === 2 
            ? &amp;lt;p&amp;gt;Component 첫번째 조건 Fales! Component 두번째 조건 True.&amp;lt;/p&amp;gt; 
            : &amp;lt;p&amp;gt;Component 첫번째 조건 Fales! Component 두번째 조건 Fales!&amp;lt;/p&amp;gt; 
          )
      }
    &amp;lt;/div&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;font-size: 28px;&quot;&gt;&lt;b&gt;React &amp;amp;&amp;amp;연산자&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React에서 사용하는 &amp;amp;&amp;amp;연산자는 자바스크립트에서 사용되는 &amp;amp;&amp;amp;연산자와 다르게 사용됩니다. &amp;amp;&amp;amp;연산자는 조건문이 True일 경우에만 동작하는 ELSE가 없는 조건문이라고 생각하면 쉽습니다. 간단한 조건문인 경우에 많이 사용됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644805363776&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function Component() {
  return (
    &amp;lt;div&amp;gt;
      {
        1 === 1 &amp;amp;&amp;amp; &amp;lt;p&amp;gt;Component가 True 인경우&amp;lt;/p&amp;gt;
      }
    &amp;lt;/div&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;React switch/case 조건문&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React에서 사용하는 switch/case 조건문 경우에는 redux에서 reducer함수에서 action의 type를 다룰 때 많이 사용되는 조건문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. switch (조건) {statement}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. statement 안에 case를 나눠줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 해당 case에서 실행되는 statement는 콜론 이후에 작성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. default는 어떠한 case에도 만족하지 않는 경우에 처리할 로직에 대해서 작성하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644805696099&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//reducer에서 사용되는 switch/case문
function reducer(state, 동작){
  switch (동작.type) {
    case '증가' :
    //증가 return 값
	  return {
        ...state,
        number: state.number + 1,
      }
    case '감소' : 
    //감소 return 값
	  return {
        ...state,
        number: state.number - 1,
      }
    default : 
      return state
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;React 오브젝트 자료형을 응용한 enum&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;enum이란 enumerated type(열거형)을 의미합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;enum은 집합을 명명하고 이를 사용하도록 하는 주요 식별자입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;react의 enum이란 경우에 따라서 다른 HTML을 보여주고 싶을 때 사용하도록 합니다. 조건에 따라서 페이지를 각각 보여주고 싶을 때 사용하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644806322057&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var UI = { 
	home : &amp;lt;a&amp;gt;홈&amp;lt;/a&amp;gt;,
  	login : &amp;lt;a&amp;gt;로그인&amp;lt;/a&amp;gt;,
  	register : &amp;lt;a&amp;gt;회원가입&amp;lt;/a&amp;gt;  
}

function Component(state) {
  //var state = 'info';
  return (
    &amp;lt;div&amp;gt;
      {
        UI[state]
      }
    &amp;lt;/div&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>&amp;amp;&amp;amp;연산자</category>
      <category>enum</category>
      <category>react</category>
      <category>react IF문</category>
      <category>리액트</category>
      <category>리액트조건문</category>
      <category>리액트조건문패턴</category>
      <category>삼항연산자</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/645</guid>
      <comments>https://redcow77.tistory.com/645#entry645comment</comments>
      <pubDate>Mon, 14 Feb 2022 11:41:00 +0900</pubDate>
    </item>
    <item>
      <title>[React] React.js의 Hooks란 무엇인가</title>
      <link>https://redcow77.tistory.com/644</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqd4Xi/btrqPiuRGSO/uXzwCPEPI6RNMP6hlhI791/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqd4Xi/btrqPiuRGSO/uXzwCPEPI6RNMP6hlhI791/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqd4Xi/btrqPiuRGSO/uXzwCPEPI6RNMP6hlhI791/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbqd4Xi%2FbtrqPiuRGSO%2FuXzwCPEPI6RNMP6hlhI791%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;React.js의 Hooks&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React에서 Hooks은 React의 새로운 기능으로써 React 16.8 버전에서 새로 추가된 기능입니다. state, component에 대한 모든 것을 바꿔놓은 기능입니다. Hooks을 이용하여 기존의 함수형 Compontent에서도 클래스형 Compontent 작업을 할 수 있게 되었습니다. 기존의 클래스형 Compontent가 가지고 있었던 복잡성, 재사용성의 단점들까지 모두 해결하기도 했습니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수형 Compontent에서 사용되는 Hook 기능중에서는 상태 관리를 할 수 있는 useState, 렌더링 직후 작업을 설정할 수 있는 useEffect의 함수가 있습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;React.js의 Hooks 사용하며 없어진 문제점&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. &lt;span style=&quot;color: #000000;&quot;&gt;Compontent 사이에서 상태와 관련된 로직을 재사용하기 어려웠습니다. Hook은 계층 변화 없이 상태 관련 로직을 재사용할 수 있도록 도와주게 되었습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 생명주기 &lt;span style=&quot;color: #000000;&quot;&gt;Compontent로 인하여 복잡한 &lt;span style=&quot;color: #000000;&quot;&gt;Compontent는 이해하기 어려웠지만 상태관련 로직이 모두 같은 공간에 함께 있기 때문에 Hook을 통하여 로직에 기반을 둔 작은 함수로 &lt;span style=&quot;color: #000000;&quot;&gt;Compontent로 나눌수 있게 되었습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;Custom Hook&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Custom Hook은 &lt;span style=&quot;color: #000000;&quot;&gt;Compontent&lt;span&gt;&amp;nbsp; 트리에 새로운 &lt;span style=&quot;color: #000000;&quot;&gt;Compontent&lt;span&gt; 를 추가하지 않고도 상태 관련 로직을 &lt;span style=&quot;color: #000000;&quot;&gt;Compontent&lt;span&gt;&amp;nbsp; 간에 재사용할 수 있게 해주는 기능입니다. Custom Hook을 만들어서 여러 &lt;span style=&quot;color: #000000;&quot;&gt;Compontent&lt;span&gt;에서 사용하더라도, 각 &lt;span style=&quot;color: #000000;&quot;&gt;Compontent에서 사용하는 state는 독립적입니다. Custom Hook은 기능이라기보다는 Convention에 가깝다고 볼 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>Hook</category>
      <category>react</category>
      <category>reactjs</category>
      <category>리액트</category>
      <category>리액트컴포넌트</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/644</guid>
      <comments>https://redcow77.tistory.com/644#entry644comment</comments>
      <pubDate>Mon, 17 Jan 2022 15:06:28 +0900</pubDate>
    </item>
    <item>
      <title>[React] React.js의 useEffect() 함수</title>
      <link>https://redcow77.tistory.com/643</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H534A/btrpRWNDPM7/Fjysr2Qn8efTumFtdl2LRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H534A/btrpRWNDPM7/Fjysr2Qn8efTumFtdl2LRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H534A/btrpRWNDPM7/Fjysr2Qn8efTumFtdl2LRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH534A%2FbtrpRWNDPM7%2FFjysr2Qn8efTumFtdl2LRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;React.js의 useEffect() 함수&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React에서 컴포넌트를 작성할 때에는 클래스형&lt;/span&gt; 컴포넌트와 함수형 컴포넌트가 있습니다. 클래스형 컴포넌트에서는 라이프사이클을 사용하게 되지만 함수형 컴포넌트에서는 라이프사이클을 사용할 수 없는데 이때 사용되는 함수가 useEffect() 함수입니다. 컴포넌트가 화면에 나타나거나, 사라질 때 또는 업데이트될 때에 렌더링을 해주는 함수입니다.(컴포넌트가 마운트 될 때 실행되는 함수입니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;useEffect() 함수의 가장 기본적으로 사용될 때의 예시입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1641442897714&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//렌더링이 완료될때마다 실행
useEffect(() =&amp;gt; {

});

//처음 렌더링이 완료된후 text값이 변경될때마다 실행
useEffect(() =&amp;gt; {

},[text]);

//처음 렌더링이 완료된후에만 실행
useEffect(() =&amp;gt; {

},[]);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처음 렌더링 된 후에 뒷정리 함수 반환후에 실행되는 예시입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1641442195919&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;useEffect(() =&amp;gt; {
	// componentDidMount
	// 컴포넌트가 렌더링 될 때마다 호출하고 싶은 함수를 이 곳에 넣습니다.
  return () =&amp;gt; {
	// componentWillUnmount
    	// 컴포넌트가 화면에서 사라질때 실행되는 함수를 이곳에 넣습니다.    
  }
}, [state, prop])

//state, prop 값이 업데이될때마다 실행&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;생명주기 메서드의 종류&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;will Method - 작업이 실행되지 직전에 호출되는 Method입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;did Method - 작업이 실행된 직후에 호출되는 Method입니다.&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>react</category>
      <category>react.js</category>
      <category>useEffect()</category>
      <category>라이프사이클함수</category>
      <category>렌더링</category>
      <category>리액트</category>
      <category>리액트렌더링</category>
      <category>리액트마운트</category>
      <category>생명주기함수</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/643</guid>
      <comments>https://redcow77.tistory.com/643#entry643comment</comments>
      <pubDate>Thu, 6 Jan 2022 13:27:10 +0900</pubDate>
    </item>
    <item>
      <title>[React] error command failed with exit code 1 [React start 에러]</title>
      <link>https://redcow77.tistory.com/642</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OehHp/btrpSlkTTZb/Q8LhycasArIFCdPALLeKf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OehHp/btrpSlkTTZb/Q8LhycasArIFCdPALLeKf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OehHp/btrpSlkTTZb/Q8LhycasArIFCdPALLeKf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOehHp%2FbtrpSlkTTZb%2FQ8LhycasArIFCdPALLeKf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;355&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 28px;&quot;&gt;&lt;b&gt;Error command failed with exit code 1. Error 발생&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React 프로젝트에서 yarn start 또는 npm start으로 서버를 시작할 때에 발생하는 에러입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;526&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYt3Hq/btrpPv9BEXP/kAiDDjfj1yN4xPVqfAmK70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYt3Hq/btrpPv9BEXP/kAiDDjfj1yN4xPVqfAmK70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYt3Hq/btrpPv9BEXP/kAiDDjfj1yN4xPVqfAmK70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYt3Hq%2FbtrpPv9BEXP%2FkAiDDjfj1yN4xPVqfAmK70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;526&quot; height=&quot;98&quot; data-origin-width=&quot;526&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치되어 있는 node의 문제가 아닌 yarn 또는 npm의 문제로 보여집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;yarn을 다시 설치하여 확인을 해보는 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img.png&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;66&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pNmis/btrpLtkJoY6/UAak5FbNULHynb8gm17Ts0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pNmis/btrpLtkJoY6/UAak5FbNULHynb8gm17Ts0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pNmis/btrpLtkJoY6/UAak5FbNULHynb8gm17Ts0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpNmis%2FbtrpLtkJoY6%2FUAak5FbNULHynb8gm17Ts0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;434&quot; height=&quot;66&quot; data-filename=&quot;img.png&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;66&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;73&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dN90fW/btrpLs0n1a1/COJH5bct2rtFxrafjU8CCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dN90fW/btrpLs0n1a1/COJH5bct2rtFxrafjU8CCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dN90fW/btrpLs0n1a1/COJH5bct2rtFxrafjU8CCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdN90fW%2FbtrpLs0n1a1%2FCOJH5bct2rtFxrafjU8CCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;749&quot; height=&quot;73&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;73&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;yarn을 다시 설치 후에 서버를 다시 기동 해보도록 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/React.js</category>
      <category>react.js</category>
      <category>yarn start</category>
      <category>yarn 재설치</category>
      <category>리액트</category>
      <category>리액트에러</category>
      <author>빨강소</author>
      <guid isPermaLink="true">https://redcow77.tistory.com/642</guid>
      <comments>https://redcow77.tistory.com/642#entry642comment</comments>
      <pubDate>Wed, 5 Jan 2022 14:29:17 +0900</pubDate>
    </item>
  </channel>
</rss>