Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

apply swr for list page #34

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

duoctvd
Copy link
Owner

@duoctvd duoctvd commented Aug 26, 2021

What I have done today

  1. Apply swr cho admin list page, refer tới 3 links say
    https://swr.vercel.app/docs/getting-started
    https://nextjs.org/docs/basic-features/data-fetching#swr
    https://nextjs.org/docs/api-routes/introduction

Em đã applued swr cho list page (hình như nó có cơ chế phân trang, nên hiện tại em đang tạm thời remove phân trang theo cách cũ). Em hy vọng cách em đang làm là đúng

  1. Apply cho form page: NOT YET

Problem

Khi làm typscript và nextjs em thường xuyên bị lỗi về không khai báo biến thế này
https://gyazo.com/fde8a3b7cc5c518f3715f1838ff84b69
https://gyazo.com/e2a8425a43026e422d4b5b146fe5d785

trước kia em bị mấy lần ở file khác, chị có hướng dẫn em, tạo view và chuyển qua view nó hết, nhưng giờ em lại bị tiếp ở file khác nữa!
src/pages/api/news/retrievenews.ts
src/pages/admin/news/list.tsx

nên em vẫn chưa thật sự biết cách fix nó là gì (nó hay thông báo Parameter 'req' implicitly has an 'any' type, nên em toàn tính dùng req: any)

@vercel
Copy link

vercel bot commented Aug 26, 2021

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/duoctvd/duoctv-trainning/AoX6pJx7EjgnnkfcHHgoupR7D1kn
✅ Preview: https://duoctv-trainning-git-feature-5useswrandmodifytemplate-duoctvd.vercel.app

[Deployment for 1ad7029 failed]

@bit-thuynt
Copy link

@duoctvd

Khi làm typscript và nextjs em thường xuyên bị lỗi về không khai báo biến thế này
https://gyazo.com/fde8a3b7cc5c518f3715f1838ff84b69
https://gyazo.com/e2a8425a43026e422d4b5b146fe5d785
nên em vẫn chưa thật sự biết cách fix nó là gì (nó hay thông báo Parameter 'req' implicitly has an 'any' type, nên em toàn tính dùng req: any)

Khi sử dụng bất kỳ biến nào em đều phải khai báo kiểu dữ liệu cho nó, còn là kiểu gì thì tùy mục đích sử dụng của em.
Trường hợp dùng any là khi em sử dụng giá trị truyền vào là từ 1 thư viện nào đó không có khai báo rõ ràng. Khi sử dụng thư viện nào đó thì phải xem kĩ docs của nó xem có hỗ trợ typescript(ts) hay không để biết cách khai báo.
Còn đối với function mà mình tự viết hoặc sử dụng từ thư viện có hỗ trợ ts thì phải khai báo rõ ràng.

Đối với cái này https://gyazo.com/fde8a3b7cc5c518f3715f1838ff84b69, em tính truyền vào url dạng gì thì em khai báo cho nó dạng đó, trường hợp này thì chắc là string

Đối với cái này https://gyazo.com/e2a8425a43026e422d4b5b146fe5d785, em đang sử dụng API thì phải. Khi đọc tài liệu hoặc tìm kiếm thì nhớ lưu ý tới ts. Như tài liệu của nextjs thì nó có hướng dẫn cho ts
image


function List() {
// let newsList: News[] = [];
const { data, error } = useSWR('/api/news/retrievenews', fetcher);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@duoctvd
Bỏ xử lý useSWR vào src/hooks/useNewListData.ts
Còn fetcher không cần sử dụng api, em gọi trực tiếp lên firebase lun
(Cái này viết ví dụ thôi nha, em phải thêm khai báo và điều chỉnh lại)

export function useNewListData() {
  const { data, error } = useSWR("useNewListData", async () => {
    return await retrieveNews(); // just sample
  });
  return {
    newsList: data,
    isError: !!error,
    isLoading: !data && !error,
  };
}

Nói chung phần sử dụng useSWR và trả về data sẽ ở trong src/hooks/useNewListData.ts
Khi sử dụng em chỉ việc gọi đơn giản vầy:

const { newsList, isError, isLoading} = useNewListData();

@duoctvd
Copy link
Owner Author

duoctvd commented Aug 27, 2021

What I have done today

  1. Applied swr for list admin: DONE - code chị demo simple em thấy nó chạy ok, k lỗi gì, nên cũng copy vào chứ k sửa gì nhiều
  2. Applied swr for form admin : DOing

import useSWR from 'swr';
import { RetrieveNews } from "../../firestore/news/retrieveNews";

export function useNewListData() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@duoctvd
Thêm kiểu trả về cho function

interface UseNewListData {
  xxxx
}
export function useNewListData(): UseNewListData {

import useSWR from 'swr';
import { RetrieveNewsById } from "../../firestore/news/retrieveNewsById";

export function useRetrieveNewsDataById(idNews:string) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@duoctvd
Tương tự phía trên, thêm kiểu trả về cho function.
Đổi tên idNews => newsId

export function useRetrieveNewsDataById(idNews:string) {

const { data, error } = useSWR("useRetrieveNewsDataById", async () => {
return await RetrieveNewsById(idNews);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@duoctvd
Cách truyền id vào như vậy đúng rồi.
Thường thì mấy file template (.tsx) sẽ viết hoa chữ đầu còn function (.ts) thì viết chữ đầu bình thường nha e.
RetrieveNewsById => retrieveNewsById

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@duoctvd
Cách truyền id vào như vậy đúng rồi.
Thường thì mấy file template (.tsx) sẽ viết hoa chữ đầu còn function (.ts) thì viết chữ đầu bình thường nha e.
RetrieveNewsById => retrieveNewsById

@bit-thuynt: Em đang dùng thế này để truyền newsId qua hooks, em đang cảm thấy nó k đc truyền qua mỗi lần request (vì còn còn dùng trong getServerSideProps), nên lúc thì nó qua đc data lúc thì nó là undifie
https://gyazo.com/f594699833b6e16bec1a73ad07de83fd

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@duoctvd
Tại router nó là bất đồng bộ nên news id lấy từ router cũng sẽ bất đồng bộ.
Vấn đề này thì xem sẽ thêm check bên trong useSWR
https://swr.vercel.app/docs/conditional-fetching#conditional

Khi nào news id có giá trị thì mới gọi get.

const { data, error } = useSWR( newsId ? "useRetrieveNewsDataById" : null, async () => {

@duoctvd
Copy link
Owner Author

duoctvd commented Aug 30, 2021

What I have done

  1. Applied swr for admin: DONE

Question

khi em đọc tài liệu về cách dùng useSWR

function useUser (id) {
  const { data, error } = useSWR(`/api/user/${id}`, fetcher)

  return {
    user: data,
    isLoading: !error && !data,
    isError: error
  }
}

/api/user/${id}`,   ---> nó thường là 1 api, nó sẽ trả về 1 data vào fetcher
fetcher -> nó sẽ là 1 asynchronous function xử lý data trả về từ api 

Nhưng cách mình dùng với firebase

>     const { data, error } = useSWR("useNewListData", async () => {
>       return await retrieveNews();
>     });

thì thật sự em vẫn chưa thật sử hiểu về useNewListData trong useSWR("useNewListData".....

Vdu

export function useNewListData() {
    const { data, error } = useSWR("useNewListData", async () => {
      return await retrieveNews();
    });

    return {
      newsList: data,
      isError: !!error,
      isLoading: !data && !error,
    } as UseNewListData;
}

lúc mình gọi
const { newsList, isError, isLoading} = useNewListData();

thì mình sẽ gọi useNewListData của
export function useNewListData()
hay
useSWR("useNewListData",

vậy chị ?

@bit-thuynt
Copy link

@duoctvd
/api/user/${id} hay là "useNewListData" thì chỉ là tên của key thôi, phần xử lý nằm ở fetcher

"useNewListData" => key

async () => {
      return await retrieveNews();
}

=> fetcher

Trong docs của nó có nói key là gì fetcher là gì.
https://swr.vercel.app/docs/options
image


lúc mình gọi
const { newsList, isError, isLoading} = useNewListData();

thì mình sẽ gọi useNewListData của
export function useNewListData()
hay
useSWR("useNewListData",

Tất nhiên là export function useNewListData() rồi.
Trong hàm này sẽ gọi tới useSWR và xử lý phần data trả về của useSWR cho phù hợp với mục đích sử dụng.

isLoading: boolean;
}

export function useNewListData() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@duoctvd
Thêm kiểu trả về ở function để khi code của mình viết nó trả về không đúng thì fix lại code.

export function useNewListData():  UseNewListData{

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@duoctvd
Thêm kiểu trả về ở function để khi code của mình viết nó trả về không đúng thì fix lại code.

export function useNewListData():  UseNewListData{

@bit-thuynt: sorry chị! em nhớ hôm qua em thêm cho nó rồi! mà chắc em adjust code debug sao sao sao push lên nó lại bị xóa đi, để em thêm lại

newsList: data,
isError: !!error,
isLoading: !data && !error,
} as UseNewListData;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@duoctvd
bỏ as chổ này vì đã khai báo trả về ở function.
Nếu có lỗi thì sửa lại chổ return hoặc kiểu trả về để cho cả 2 khớp nhau.

import useSWR from 'swr';
import { retrieveNewsById } from "../firestore/news/retrieveNewsById";

interface useRetrieveNewsDataById {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@duoctvd
Đối với interface thì viết hoa chữ đầu

news: data,
isError: !!error,
isLoading: !data && !error,
} as useRetrieveNewsDataById;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tương tự ở trên, bỏ as useRetrieveNewsDataById

@duoctvd
Copy link
Owner Author

duoctvd commented Aug 31, 2021

What I have done

  1. Fix bug về khai báo interface và biến: DONE
  2. Apply https://nextjs.org/docs/advanced-features/module-path-aliases : DONE
  3. Modulization template Cấu trúc lại template theo Layered Architecture #33 (comment) : Doing

Problem

  1. về aliases for firebase.js file, hiện tại file đó em vẫn đang để ngoài root của project, nên vẫn đang dùng tương đối
vdu : `src/pages/login.tsx`
import { firebase } from "../../firebase";
  1. Về Modulization template : hiện tại em đã thử tách 2 file bên dưới
    src\components\templates\admin\news\list\index.tsx
    src\components\templates\admin\news\list\presenter.tsx
    và đang xem thử về cách xử lý và truyền data qua lại giữa function ở 2 file

import { useState } from "react";
import { newsPagination } from "src/firestore/news/newsPagination";

// export default function NewsListTemplate({ newsList }: { newsList: News[] }) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@duoctvd
Những xử lý sau vẫn nằm trong NewsListTemplate
Em chỉ cần move phần layout sang presenter thôi

import { newsPagination } from "src/firestore/news/newsPagination";
import { nextPage,prevPage } from "src/components/templates/admin/news/list/index";

export default function NewsListTemplate({ newsList }: { newsList: News[] }) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NewsListTemplate => NewsListPresenter

Comment on lines +16 to +19
const router = useRouter();
var [newsListResult, setNewsListResult] = useState(newsList);
const [end, setEnd] = useState(false);
const [start, setStart] = useState(true);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mấy xử lý này là thuộc container (news/list/index.tsx)

@@ -1,7 +1,7 @@
import React from "react";
import Head from "next/head";
import styled from "styled-components";
import NewsListTemplate from "src/components/templates/admin/news/list";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chổ này vẫn giữ import như cũ
import NewsListTemplate from "src/components/templates/admin/news/list";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants