[Next.js] 구성 요소 및 상태 관리를 위한 파일 분할 및 설계
개시하다
지금까지 나는 어떻게 설치해야 할지 몰라서 조사를 진행하여 시행착오를 쓴 후에 실현된 방법을 썼다
이번에는 이룰 수 있지만 더 나은 이룰 수 없을까?나는 이 방향으로 한번 쓰고 싶다.
쓴 내용은 Next입니다.js에서 구현된 일람과 검색 기능을 가진 화면의 구성 요소와 상태 관리에 대한 파일 분할과 디자인.
넥스트입니다.js(React)에 관해서 제가 처음에 썼을 때는 1년 정도밖에 안 됐는데 업무상 쓴 적이 없어서 다른 PJ의 구성을 거의 몰랐지만 제 마음속의 디자인이 안정적이어서 쓰고 싶었어요.🙏
설명할 페이지
이번 해설의 페이지는 캐릭터와 LP로 자신이 실행한 트위터를 검색할 수 있는 깨알 독서 일람이 가능한 페이지다.
다음은 이 페이지의 신구 문서 구성과 상태 관리의 디자인에 대해 설명한다.
구형
먼저 낡은 디자인의 문서 구성을 소개한다.
pages/lounge/tweet.tsx
를 기준으로 사용하는 API와 어셈블리는 동일한 디렉토리 구조입니다(일부 공통 어셈블리도 있음).페이지
페이지 파일에서
useState
로 깨진 생각의 일람, 검색을 관리하는 조건(캐릭터와 LP).검색된 각 구성 요소
components/lounge/tweet/character.tsx
에서 사용자가 선택한 조건components/lounge/tweet/lp.tsx
을 받아들여 상태를 유지합니다.검색을 누르면 저장된 검색 조건을 이용하여 검색 처리를 합니다.
pages/lounge/tweet.tsx
export default function LoungeTweet() {
const [tweetList, setTweetList] = useState([]);
const [allTweetList, setAllTweetList] = useState([]);
const [selectCharacterList, setSelectCharacterList] = useState([]);
const [selectLpList, setSelectLpList] = useState([]);
useEffect(() => {
(async () => {
const tmpTweetList = await getTweet(); // lib/lounge/tweet/api.ts
setTweetList(tmpTweetList);
setAllTweetList(tmpTweetList);
})();
}, []);
const search = () => {
const searchTweetList = allTweetList.filter((tweet) => {
// 検索処理
});
setTweetList(searchTweetList);
};
const changeCharacter = (characterList) => {
setSelectCharacterList(characterList);
};
const changeLp = (lpList) => {
setSelectLpList(lpList);
};
return (
<Layout>
<H1>ラウンジ募集呟き一覧</H1>
<div>
<Character changeCharacter={changeCharacter} /> {/* components/lounge/tweet/character.tsx */}
<Lp changeLp={changeLp} /> {/* components/lounge/tweet/lp.tsx */}
<Button onClick={search}>検索</Button> {/* components/common/button.tsx */}
<LoungeList tweetList={tweetList} /> {/* components/lounge/tweet/list.tsx */}
</div>
</Layout>
);
}
구성 요소
캐릭터와 LP의 검색 성분이 거의 같기 때문에 LP의 성분을 소개해 드리겠습니다.
검색 조건을 표시하고 검색 조건을 클릭한 후 구성 요소
setXXX
에서 상태를 유지하고 setXXX
에서 받은 함수(이번 예는props
를 실행하며 검색 조건을 부모에게 전달합니다.components/lounge/tweet/lp.tsx
export default function LoungeTweetLp(props) {
const { changeLp } = props;
const [selectLpList, setSelectLpList] = useState([]);
const clickLp = (lp) => {
let tmpSelectLpList = [];
if (selectLpList.includes(lp)) {
tmpSelectLpList = selectLpList.filter((l) => l.id !== lp.id);
} else {
tmpSelectLpList = [...selectLpList, lp];
}
setSelectLpList(tmpSelectLpList);
changeLp(tmpSelectLpList);
};
return (
<div>
<Details
summary={(
<div>
<span>LP</span>
<p>
{selectLpList.length === 0 ? '指定なし' : selectLpList.map((selectLp) => (
<p>{selectLp.name}</p>
))}
</p>
</div>
)}
>
<ul>
{lps.map((lp) => (
<li>
<input type="checkbox" id={lp.id} onChange={() => clickLp(lp)} checked={selectLpList.includes(lp)} />
<label htmlFor={lp.id}>{lp.name}</label>
</li>
))}
</ul>
</Details>
</div>
);
}
해설
첫 번째 피쳐는 시트 어셈블리의 상태를 유지합니다.
설치할 때 연결고리를 구성 요소 밖으로 뽑아서 쓸 수 있는지 몰라서 구성 요소에 적혀 있습니다.
나는 단지 독립된 고리만 한 번 보았을 뿐 전혀 이해하지 못했다.
또한 각 페이지 구성 요소는 검색 조건의 상태를 유지합니다.
검색 처리는 페이지에서 이루어지기 때문에 구성 요소에 검색 조건을 가지고 있을 필요는 없지만, 실행할 때 '구성 요소 안에 선택한 조건을 표시합니다' = '구성 요소 안에 표시된 조건이 있습니다'.
나는 이 디자인에 다음과 같은 과제가 있다고 생각해서 팩스를 결정했다.
지금
새 디자인 제작
changeLp
으로 상태 관리와 관련된 처리를 구성 요소 밖으로 제출합니다.연결시키다
페이지 구성 요소에서 쓴 상태를 저장하는 처리, 검색 조건의 디스플레이 텍스트, 검색 처리 등을 총괄했다.
기본적으로 낡은 코드에서 복사된 것으로 새 것이 없다.
hooks/lounge/useTweet.ts
export const useLoungeTweet = () => {
const [tweetList, setTweetList] = useState([]);
const [allTweetList, setAllTweetList] = useState([]);
const [selectLpList, setSelectLpList] = useState([]);
const DEFAULT_TEXT = '指定なし';
const [selectLpText, setSelectLpText] = useState(DEFAULT_TEXT);
useEffect(() => {
(async () => {
const tmpTweetList = await getTweet();
setTweetList(tmpTweetList);
setAllTweetList(tmpTweetList);
})();
}, []);
const search = () => {
const searchTweetList = allTweetList.filter((tweet) => {
// 検索処理
});
setTweetList(searchTweetList);
};
const setSelectLp = (lp) => {
let tmpSelectLpList = [];
if (selectLpList.includes(lp)) {
tmpSelectLpList = selectLpList.filter((l) => l.id !== lp.id);
} else {
tmpSelectLpList = [...selectLpList, lp];
}
setSelectLpList(tmpSelectLpList);
if (tmpSelectLpList.length === 0) {
setSelectLpText(DEFAULT_TEXT);
} else {
setSelectLpText(tmpSelectLpList.map((_lp) => {
return _lp.name;
}).join('\n'));
}
};
const checkedLp = (lp) => {
return selectLpList.includes(lp);
};
return {
tweetList,
selectLpText,
setSelectLp,
checkedLp,
search,
};
};
페이지
상태 관련 처리 및 읽어들이기 처리
hooks/lounge/useTweet.ts
가 없으며 이 프로세스만 가져와 각 어셈블리에 전달할 수 있습니다.pages/lounge/tweet.tsx
export default function LoungeTweet() {
const {
tweetList,
search,
setSelectCharacter,
setSelectLp,
checkedLp,
checkedCharacter,
selectCharacterText,
selectLpText,
} = useLoungeTweet();
return (
<Layout>
<H1>ラウンジ募集呟き一覧</H1>
<div>
<Character set={setSelectCharacter} checked={checkedCharacter} text={selectCharacterText} />
<Lp set={setSelectLp} checked={checkedLp} text={selectLpText} />
<Button onClick={search}>検索</Button>
<LoungeList tweetList={tweetList} />
</div>
</Layout>
);
}
구성 요소
상태에 대한 처리가 사라짐
useLoungeTweet
, 받은 것만 사용.components/lounge/tweet/lp.tsx
export default function LoungeTweetLp(props) {
const { text, set, checked, } = props;
return (
<div>
<Details
summary={(
<div>
<span>LP</span>
<p>{text}</p>
</div>
)}
>
<ul>
{lps.map((lp) => (
<li>
<input type="checkbox" id={lp.id} onChange={() => set(lp)} checked={() => checked(lp)} />
<label htmlFor={lp.id}>{lp.name}</label>
</li>
))}
</ul>
</Details>
</div>
);
}
해설
홀로 갈고리 상태의 처리 등 통일, 낡은 디자인의 과제가 해결됐다.
재활용 정보
낡은 것과 새로운 페이지의 재사용은 그다지 고려되지 않는다.
이번 해설은 일람과 검색의 페이지로 이 사이트에도 제작된 페이지가 있다.
목록 및 검색 페이지와 비슷한 UI 구성 요소가 있으며 이제 다른 파일에서 사용할 수 있습니다.
또 다른 이유로 이번 코드에는 나타나지 않았고
props
등의 유형 정의와 재사용은 미묘한 차이를 흡수하기 위한 조건 지점이 구성 요소로 늘어날 것으로 보인다.이 사이트에서 페이지를 넘기는 재활용에 관해서 저는 아직 좋은 점을 찾지 못했습니다. 앞으로 수정하는 과정에서 좋은 곳에 떨어지면 다시 쓰고 싶습니다.
최후
다른 디자인을 더 알고 싶으니 마음대로 평론해 주세요.👍
추기 2021/10/27
나는 본 블로그에서 제작한 훅스 테스트에 관한 블로그를 썼다.
Reference
이 문제에 관하여([Next.js] 구성 요소 및 상태 관리를 위한 파일 분할 및 설계), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/tiwu_dev/articles/2504a20732d305텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)