React 및 GraphQL - 15를 사용하여 Reddit 클론 만들기
22522 단어 reactredditclonetypescriptgraphql
이 블로그 게시물은 원래 내 블로그 사이트에 게시되었으며 여기에서 찾을 수 있습니다.
이 블로그 게시물에서 우리는 페이지 매김을 설정할 것입니다. 따라서 많은 데이터를 데이터베이스에 시드해야 합니다. mockaroo 사이트를 사용하여 모의 데이터를 생성하고 해당 데이터를 SQL 쿼리로 내보낼 수 있습니다.
그런 다음 create migration 명령을 실행하여 서버 애플리케이션에서 마이그레이션 파일을 생성합니다.
npx typeorm migration:create -n FakePost
해당 마이그레이션 파일에는
up
및 down
라는 2개의 메서드가 있습니다. 이 코드 줄을 up
메서드에 추가합니다.await queryRunner.query(`
... mockaroo queries goes here `);
그런 다음 이 마이그레이션 파일을 실행하도록 서버 인덱스 파일을 변경합니다. 해당 파일을
migration
폴더로 이동할 수 있습니다. createConnection
메서드에 마이그레이션 속성을 추가합니다.
migrations: [path.join(__dirname, "./migrations/*")],
그런 다음 해당 메서드 아래에 이 코드 줄을 추가하여 마이그레이션을 실행합니다.
await conn.runMigrations();
이 시점에서 우리는 게시물의 텍스트를 반환하지 않습니다. 그러나 우리는 홈 페이지에 전체 텍스트를 표시하고 싶지 않습니다. 홈 페이지에는 제한된 수의 문자만 표시할 수 있습니다.
@Resolver(Post)
에 Resolver 주석을 추가할 수 있으며 FiledResolver를 추가하고 있습니다.
@FieldResolver(() => String)
textSnippet(@Root() root: Post) {
return root.text.slice(0, 50);
}
또한 마지막 게시물 타임스탬프를 가져와서 이전 게시물을 반환하는
cursorPagination
메서드를 사용하고 있습니다. posts
메서드를 사용자 쿼리 빌더로 변경하고 결과를 제한 개수로 반환할 수 있습니다. 여기에서 limit
및 cursor
로 2개의 매개변수를 사용합니다.
async posts(
@Arg("limit", () => Int) limit: number,
@Arg("cursor", () => String, { nullable: true }) cursor: string | null
): Promise<Post[]> {
// previously we took all the posts
// return await Post.find();
// using query builder
const realLimit = Math.min(50, limit);
const qb = getConnection()
.getRepository(Post)
.createQueryBuilder("p")
.orderBy('"createdAt"', "DESC")
.take(realLimit);
if (cursor) {
// take the old post using cursor
qb.where('"createdAt" < :cursor', {
cursor: new Date(parseInt(cursor)),
});
}
return qb.getMany();
}
이제 백엔드 코드가 완성되었습니다. 이제 이 두 매개변수와 일치하도록 프런트 엔드
graphql
쿼리를 변경해야 합니다.
query Posts($limit: Int!, $cursor: String) {
posts(cursor: $cursor, limit: $limit) {
id
createdAt
updatedAt
title
textSnippet
}
}
이
graphql
쿼리를 변경한 후 yarn gen
명령을 실행합니다. 게시물을 검색하기 위해 생성된 메서드를 업데이트합니다.이제 일부
chakra-ui
구성 요소를 추가하여 게시물의 전망을 변경할 수 있습니다.헤더를 추가하고 Create Post 링크를 재정렬할 수 있습니다.
<Flex align="center">
<Heading>Reddit Clone</Heading>
<NextLink href="/create-post">
<Link ml="auto">Create Post</Link>
</NextLink>
</Flex>
처리해야 하는 몇 가지 시나리오가 있습니다. 하나는 데이터가 없고 여전히 가져오는 경우 아래 메시지를 표시해야 합니다.
if (!fetching && !data) {
return <div>there is some error in graphql query</div>;
}
fetching
를 사용하려면 graphql
쿼리에서 할당해야 합니다.
const [{ data, fetching }] = usePostsQuery({
// ... rest of the code
게시물 스니펫과 함께 게시물을 표시하도록 아래와 같이
post
UI를 업데이트할 수 있습니다.
<Stack spacing={8}>
{data!.posts.map((p) => {
return (
<Box key={p.id} p={5} shadow="md" borderWidth="1px">
<Heading fontSize="xl">{p.title}</Heading>
<Text mt={4}>{p.textSnippet} </Text>
</Box>
);
})}
</Stack>
그런 다음 데이터가 있는 경우 더 많은 게시물을 로드하는 버튼을 표시할 수 있습니다. 종료
</Layout>
태그 위의 코드를 아래에 추가합니다.
{data ? (
<Flex>
<Button onClick={() => { }); } m="auto" my={8} isLoading={fetching} >
load more
</Button>
</Flex>
) : null}
이제 캐시에서
createUrqlClient
에 페이지 매김 리졸버를 추가합니다. 캐시에 있는 게시물을 새 게시물에 추가하는 기능입니다.
const cursorPagination = (): Resolver => {
return (_parent, fieldArgs, cache, info) => {
const { parentKey: entityKey, fieldName } = info;
const allFields = cache.inspectFields(entityKey);
console.log("allFields: ", allFields);
const fieldInfos = allFields.filter((info) => info.fieldName === fieldName);
const size = fieldInfos.length;
if (size === 0) {
return undefined;
}
const fieldKey = `${fieldName}(${stringifyVariables(fieldArgs)})`;
const isItInTheCache = cache.resolve(entityKey, fieldKey);
info.partial = !isItInTheCache;
const results: string[] = [];
fieldInfos.forEach((fi) => {
const data = cache.resolve(entityKey, fi.fieldKey) as string[];
console.log(data)
results.push(...data);
});
return results;
};
};
교환하려면 이것을
cacheExchange
로 설정해야 합니다.
resolvers: {
Query: {
posts: cursorPagination(),
},
},
이제
onClick
기능을 추가할 수 있습니다. 상태를 사용하여 커서를 설정할 수 있습니다. 먼저 cursor
의 초기 조각상을 만듭니다.
const [variables, setVariables] = useState({
limit: 10,
cursor: null as null | string,
});
그런 다음 버튼을 클릭하면 커서가 마지막 게시물의 타임스탬프로 변경됩니다. 이렇게 하면 새 게시물을 로드할 수 있습니다.
<Button
onClick={() => {
setVariables({
limit: variables.limit,
cursor: data.posts[data.posts.length - 1].createdAt,
});
}}
m="auto"
my={8}
isLoading={fetching}
>
// ...rest of the code
이제 뷰에서 새 게시물을 업데이트하는 것을 볼 수 있습니다.
읽어주셔서 감사합니다. 이와 관련하여 질문할 사항이 있으면 여기에 댓글을 남겨주세요. 또한 내 이해에 따라 이것을 썼습니다. 따라서 잘못된 점이 있으면 주저하지 말고 저를 수정하십시오. 정말 감사합니다.
오늘의 친구들을 위한 것입니다. 곧 봐요. 고맙습니다.
참조:
이 기사 시리즈는 . 이것은 놀라운 튜토리얼이며 확인하는 것이 좋습니다.
기본 이미지credit
Reference
이 문제에 관하여(React 및 GraphQL - 15를 사용하여 Reddit 클론 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rasikag/creating-a-reddit-clone-using-react-and-graphql-15-1aon텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)