useEffect

리액트 컴포넌트의 사이드 이펙트를 제어하는 새로운 React Hook

 

사이드 이펙트

우리말로 '부작용'이라는 뜻

리액트에서는 '부수적인 효과', 파생되는 효과; 정도로 해석 가능

 

 

의존성 배열 dependency array

  useEffect(()=> {console.log(`count: ${count}`)},[count]);

 

두번째로 받는 인자([count])가 변경될 때마다 useEffect 

 

  // 1. 마운트: 탄생
  useEffect(() => {
    console.log("mount")
  }, []);

  // 2. 업데이트: 변화, 리렌더링
  useEffect(()=> {  
    if(!isMount.current) {
    isMount.current= true;
    return;
    }
    console.log("update");
})
  useEffect(()=> {  
  	// 3. 죽음: 클린업, 정리함수
    return () => {
    	console.log("unmount");
    }
}, [])

 

profile.component.html

<form [formGroup]="editProfileForm" class="profile_input" (ngSubmit)="onSubmit()">
        <mat-form-field>
            <mat-label>Name</mat-label>
            <input class="data-input"  type="text" matInput formControlName="name" autocomplete="text">
            <mat-error *ngIf="editProfileForm.controls['name'].hasError('required')">
                name is required.
            </mat-error>
        </mat-form-field>               

    <mat-form-field>
        <mat-label>New Password</mat-label>
        <input type="password" matInput formControlName="password" autocomplete="password">
        <mat-error
      *ngIf="editProfileForm.controls['password'].hasError('minlength') || editProfileForm.controls['password'].hasError('maxlength')">Password is required</mat-error>
    </mat-form-field>

    <mat-form-field>
        <mat-label>Confirm Password</mat-label>
        <input type="password" matInput formControlName="confirmPassword" autocomplete="password">
        <mat-error *ngIf="editProfileForm.controls['confirmPassword'].hasError('minlength') || editProfileForm.controls['confirmPassword'].hasError('maxlength')">ConfirmPassword is required</mat-error>
    </mat-form-field>
    <mat-error
        *ngIf="editProfileForm.errors?.['PasswordNoMatch'] && (editProfileForm.touched || editProfileForm.dirty)">
        password does not match
    </mat-error>    

    <button class="submitBtn" mat-flat-button (click)="onSubmit()">Edit</button>
</form>

 

 

profile.component.ts

fb = inject(FormBuilder);

editProfileForm: FormGroup = this.fb.group({
    name: new FormControl('', [Validators.required]),
    email: new FormControl('', [Validators.required, Validators.email]),
    password: new FormControl('', [
      Validators.required,
      Validators.minLength(4),
      Validators.maxLength(15),
    ]),
    confirmPassword: new FormControl('', [
      Validators.required,
      Validators.minLength(4),
      Validators.maxLength(15),
    ]),
  },
  { validators: confirmPasswordValidator }
);

 

 

confirm-password.validator.ts

import {
    AbstractControl,
    ValidationErrors,
    ValidatorFn,
} from '@angular/forms';

export const confirmPasswordValidator: ValidatorFn = (
    control: AbstractControl
): ValidationErrors | null => {
    const password = control.get('password')?.value;
    const confirmPassword = control.get('confirmPassword')?.value;
    console.log(password, confirmPassword)
    console.log(password === confirmPassword)
    return password === confirmPassword
        ? null
        : { PasswordNoMatch: true };
};

 

 

profile.service.ts

  // 프로필 정보 업데이트하기
  updateProfile(formData: any): Observable<HttpResMsg<any>> {
    return this.http.patch<HttpResMsg<any>>(
      this.baseUrl + '/admin/profileChange',
      formData
    );
  }
<ng-container matColumnDef="download">
    <th mat-header-cell *matHeaderCellDef></th>
    <td mat-cell *matCellDef="let element">    
        <a [href]="element.location" target="_blank">      
            <mat-icon>cloud_download</mat-icon>
        </a>
    </td>
</ng-container>

 

 

<a [href]="element.location" target="_blank"></a> 태그로 감싸주면 된다. 

 

'Framework > Angular' 카테고리의 다른 글

[React] useEffect  (0) 2024.06.28
Password form validator  (0) 2024.05.20
Angular pdf 폰트 깨짐 현상 버그 해결하기  (0) 2024.04.15
Angular pdfjs 버전 에러  (0) 2024.03.27

 

없는 폰트일 때에 폰트 빼고 불러오는 버그 발견

 

기존 코드 

(getDocument 하는 부분은 다 해야 됌)

  // pdf 파일 읽기
  async readFile(file: File) {
    this.pdfFile.update(() => file)
    const fileReader = new FileReader();
    fileReader.onload = async (e) => {
      const arrayBuffer: ArrayBuffer | null = fileReader.result as ArrayBuffer;
      if (arrayBuffer) {
        const loadingTask = pdfjsLib.getDocument({ data: arrayBuffer });
        const pdfDocument = await loadingTask.promise
        await this.storePdfInfo(pdfDocument)
        this.pdfLength.update(() => pdfDocument.numPages)
        this.currentPage.set(1)
      }
    };
    await fileReader.readAsArrayBuffer(file);
  }

 

 

추가할 코드

const CMAP_URL = environment.cmapURL; // --> 나중에 서버로 이동할지 check.
const CMAP_PACKED = true;
    
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED

 

 

추가된 코드

  // pdf 파일 읽기
  async readFile(file: File) {
    const CMAP_URL = environment.cmapURL; // --> 나중에 서버로 이동할지 check.
    const CMAP_PACKED = true;

    this.pdfFile.update(() => file)
    const fileReader = new FileReader();
    fileReader.onload = async (e) => {
      const arrayBuffer: ArrayBuffer | null = fileReader.result as ArrayBuffer;
      if (arrayBuffer) {
        const loadingTask = pdfjsLib.getDocument({
          data: arrayBuffer,
          cMapUrl: CMAP_URL,
          cMapPacked: CMAP_PACKED,
        });
        const pdfDocument = await loadingTask.promise
        await this.storePdfInfo(pdfDocument)
        this.pdfLength.update(() => pdfDocument.numPages)
        this.currentPage.set(1)
      }
    };
    await fileReader.readAsArrayBuffer(file);
  }

 

 

 

환경설정 파일, 하단 코드 추가해줘야 한다.

  • environment.development.ts
  • environment."파일명".ts
  • environment.ts
cmapURL: '/assets/lib/cmaps/'

 

 

 

 

node_module 에 있는 cmaps를  저 경로로 옮겨준다 

 

 

'Framework > Angular' 카테고리의 다른 글

[React] useEffect  (0) 2024.06.28
Password form validator  (0) 2024.05.20
Angular html에서 간단하게 다운로드 기능 추가하기  (0) 2024.04.17
Angular pdfjs 버전 에러  (0) 2024.03.27
ERROR Error: Uncaught (in promise): UnknownErrorException: The API version "3.11.174" does not match the Worker version "3.8.162".Error at BaseExceptionClosure (pdf.js:446:29) at Object.defineProperty.value (pdf.js:449:2) at __w_pdfjs_require__ (pdf.js:17849:41) at pdf.js:18129:13 at pdf.js:18140:2 at pdf.js:18143:11 at webpackUniversalModuleDefinition (pdf.js:25:36) at 1150 (pdf.js:32:2) at __webpack_require__ (bootstrap:19:1) at 5065 (create-space-dialog.component.html:3:47) at resolvePromise (zone.js:1193:31) at zone.js:1100:17 at zone.js:1116:33 at asyncGeneratorStep (asyncToGenerator.js:6:1) at _throw (asyncToGenerator.js:25:1) at _ZoneDelegate.invoke (zone.js:368:26) at Object.onInvoke (core.mjs:11083:33) at _ZoneDelegate.invoke (zone.js:367:52) at Zone.run (zone.js:129:43) at zone.js:1257:36

 

 

이 에러는 PDF.js 라이브러리의 API 버전과 Worker 버전이 서로 일치하지 않아 발생한 것으로 보입니다.

PDF.js는 메인 스레드와 별도의 워커 스레드에서 동작하는 두 부분으로 구성됩니다. 메인 스레드는 PDF 파일을 해석하고 표시하는 주요 작업을 처리하고, 워커 스레드는 병렬로 페이지 렌더링을 수행합니다.

이 에러는 메인 스레드에서 사용되는 PDF.js의 API 버전과 워커 스레드에서 사용되는 버전이 서로 호환되지 않는 경우에 발생합니다. 이것은 보통 PDF.js 라이브러리의 API 버전과 워커 스레드의 버전이 서로 일치하지 않는 경우에 발생할 수 있습니다.

해결 방법은 PDF.js의 라이브러리와 워커 스레드를 서로 호환되는 버전으로 업데이트하는 것입니다. 이를 위해서는 PDF.js 라이브러리와 워커 스레드의 버전을 일치시키거나, 라이브러리와 워커 스레드를 모두 최신 버전으로 업데이트해야 할 수 있습니다.

또한, PDF.js를 사용하는 코드에서 버전 충돌이 발생하지 않도록 주의해야 합니다. 동일한 버전의 PDF.js 라이브러리와 워커 스레드를 사용하는 것이 좋습니다.

 

 

나는 

 

npm uninstall pdfjs-dist

 

으로 기존 라이브러리를 지우고

 

 

https://www.npmjs.com/package/pdfjs-dist?activeTab=versions

 

pdfjs-dist

Generic build of Mozilla's PDF.js library.. Latest version: 4.0.379, last published: 3 months ago. Start using pdfjs-dist in your project by running `npm i pdfjs-dist`. There are 1567 other projects in the npm registry using pdfjs-dist.

www.npmjs.com

여기에서 버전 찾아서 

 

npm i pdfjs-dist@3.8.162

 

버전에 맞는 걸로 다시 설치함

+ Recent posts