React 프로젝트: 인증이 있는 게시물의 해시태그 — 파트 #2
33071 단어 reactgridlayoutrouterlayout
ReactJ의 기초와 시작 방법에 대해 전혀 모르는 경우 link을 참조할 수 있습니다.
부품 시리즈에 대한 빠른 링크:
1 부 -
PART #2 - ReactJS는 UI를 구성 요소로 분할합니다. 구성 요소(이 게시물)
파트 #3 -
파트 #4 -
파트 #5 - styled-component의 고급 사용에 대한 기본 사항
어떤 단계에서든 막히면 Github repo을 참조하십시오.
완료된 프로젝트를 찾으려면 Demo link
Components let you split the UI into independent, reusable pieces, and think about each piece in isolation
React에서는 UI를 구성 요소별로 분할하는 것이 중요하므로 필요한 구성 요소 수를 확인하겠습니다.
보시다시피 7가지 구성 요소가 눈에 띕니다.
구성 요소를 만들 때 묻는 질문:
내 구성 요소는 무엇을 해야 합니까?! 🤔
상태 관리 — 구성 요소가 저장소를 구독합니다.
데이터 가져오기 — 저장소에서 상태를 가져옵니다.
UI 프리젠테이션 — 렌더링
비즈니스 로직 — 애플리케이션의 비즈니스 로직과 연결되어 있습니다.
구성 요소를 하나씩 설명하겠습니다.
헤더 구성요소
헤더 구성 요소는 매우 간단하며 프로젝트 제목을 포함합니다.
import React from "react";
const Heading = ({ title }) => {
return (
<div className="col">
<h1>{title}</h1>
</div>
);
};
export default Heading;
필터 구성요소
필터 구성 요소는 다음과 같아야 합니다.
입력 상태를 저장하기 위해 이 구성 요소에서 사용자 지정 후크를 사용합니다.
import React from 'react';
import { useDispatch } from 'react-redux';
import useFilterHook from '../../hooks/useFilterHooks';
import { authorsFiltering } from './author-slice';
import { useTranslation } from "react-i18next";
const filterTypes = [
{
type: 'Radio',
default: 'mr',
selected: 'Mr',
list: [
{ label: 'All', value: 'All' },
{ label: 'Mr.', value: 'mr' },
{ label: 'Miss.', value: 'miss' },
],
optional: false,
queryParamKey: 'title',
placeholder: null,
title: 'title',
},
{
type: 'Text',
default: '',
selected: '',
list: [],
optional: false,
queryParamKey: 'firstName',
placeholder: 'Search by FirstName',
title: 'first_name',
},
{
type: 'Text',
default: '',
selected: '',
list: [],
optional: false,
queryParamKey: 'lastName',
placeholder: 'Search by LastName',
title: 'last_name',
},
{
type: 'Text',
default: '',
selected: '',
list: [],
optional: false,
queryParamKey: 'email',
placeholder: 'Search by Email',
title: 'Email',
},
];
const Filter = () => {
const dispatch = useDispatch();
const { t: translation } = useTranslation();
const filtering = () => {
dispatch(authorsFiltering({ search_keys: inputs }));
}
const {inputs, handleInputChange, handleSubmit} = useFilterHook({ }, filtering);
return (
<div>
<h4> {translation('filters')} </h4>
<form onSubmit={handleSubmit} autoComplete="off">
{filterTypes.map((filter) => (
<article className='card-group-item' key={`${filter.title}`}>
<header className='card-header'>
<h6 className='border-bottom border-3'>
{translation(filter.title)}
</h6>
</header>
<div className='card-body'>
{filter.type === 'Radio' ? (
filter.list.map((item) => (
<label className='form-check' key={`${item.label}`}>
<input
type='radio'
name={filter.queryParamKey}
value={item.value}
onChange={ handleInputChange}
/>
<span className='form-check-label'> {item.label}</span>
</label>
))
) : (
<input
className='form-check-input'
type='text'
name={filter.queryParamKey}
onChange={handleInputChange}
/>
)}
</div>
</article>
))}
<br />
<button type='submit' className='btn btn-primary left'>
{ translation('apply')}
</button>
</form>
</div>
);
};
Filter.displayName = 'Filter';
export default Filter;
작성자 구성 요소
작성자 구성 요소는 다음을 수행해야 합니다.
import React, { useEffect, lazy } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { useAuthors } from './authors-hooks';
import { authorSelector, authorsReceived } from './author-slice';
const AuthorListView = lazy(() => import('./author-listing-view'));
const NoResult = lazy(() => import('../../components/empty-list'));
const Loader = lazy(() => import('../../components/loader'));
const AuthorListing = () => {
const { authors, filters: authorFilter } = useSelector(authorSelector);
const dispatch = useDispatch();
const { data, isFetching } = useAuthors();
const renderStatus = data && data.data;
useEffect(() => {
if (renderStatus) {
dispatch(authorsReceived(data.data));
}
}, [renderStatus]); // eslint-disable-line react-hooks/exhaustive-deps
const authorItemList = authors.map((authorDetails) => {
return (
<AuthorListView
key={`${authorDetails.firstName}-${authorDetails.lastName}`}
user={authorDetails}
/>
);
});
const authorFilterView = Object.keys(authorFilter).map((filter) => {
return (
<button class="btn btn-secondary ml-4">{filter.toUpperCase()} <span class="badge">{ authorFilter[filter] } </span></button>
);
});
if (isFetching) {
return <Loader />;
}
return <div>
<div>{ authorFilterView }</div>
{authors.length ? authorItemList : <NoResult />}
</div>;
};
AuthorListing.displayName = 'AuthorsListing';
export default AuthorListing;
포스트 컴포넌트
게시물 구성요소는 다음과 같아야 합니다.
import React, { lazy } from 'react';
import { usePosts } from './posts-hooks';
const PostListView = lazy(() => import('./post-listing-view'));
const NoResult = lazy(() => import('../../components/empty-list'));
const Loader = lazy(() => import('../../components/loader'));
const PostsListing = () => {
const { data, isFetching } = usePosts();
const posts = (data && data.data) || [];
const postItemList = posts.map((postDetails) => {
return <PostListView key={`${postDetails.text}`} post={postDetails} />;
});
if (isFetching) {
return <Loader />;
}
return <div>{posts.length ? postItemList : <NoResult />}</div>;
};
PostsListing.displayName = 'PostsListing';
export default PostsListing;
계속하려면
Reference
이 문제에 관하여(React 프로젝트: 인증이 있는 게시물의 해시태그 — 파트 #2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/selvaece25/react-project-hashtags-for-posts-with-auth-part-2-3fn5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)