APPJAM]タイプスクリプトによる選択ボタン機能
10999 ワード
YamatypescriptでどうやってそのChiprops typeを手に入れてselectボタンを自分で作ったのか...
buttonラベルを使用してselectボタンを直接作成しています.必要なことは次のとおりです.
選択可能な条件(dropdown item)入力ボタン
上下切替アイコン(isOpenに依存)
dropdown itemを選択すると、ボタンが初期化されます.一度に1つのボタンだけを開く
Active効果:border,shadow dropdown item接続api を選択
カテゴリが選択されていない場合は、を無効にします.
総時間、価格、開設日、繰り返し視聴時間、質疑応答時間によって、ドロップダウンメニューごとに異なります.
isOpen:trueでArrow方向が変わりました. 図は、の各選択ボタンのドロップダウンメニューである. onClickSortingItem関数は、value(選択された選択ボタンの名前)とitem(選択されたドロップダウンメニュー)を受信し、どのメニューをボタンに入れるかの情報を取得します.
1つのドロップダウンメニューが開いている場合、他のは閉じなければなりません.1回に複数を管理します.
=>オブジェクトに「開くかどうか」(isOpen)ドロップダウンリストを入れます.ex){「定期視聴時間」:true,...}
isOpenオブジェクトを作成するには、forEach文をsortingCriteria配列として使用してfalseの値を持つオブジェクトを作成します.
switch (criteria) {
case criteria:
setIsOpen({
...sortingObject,
[criteria]: !isOpen[criteria],
});
break;
}
};
//dropdownドロップダウン・リスト・タイプの定義
export type IDropListName = {
[key in sortingType]: string[];
};
const selectedItemName: ISelectedItemName = {};
sortingCriteria.forEach((element) => (isSelectedObject[element] = false));
sortingCriteria.forEach((element) => (selectedItemName[element] = ""));
const [isSelected, setIsSelected] = useState(isSelectedObject);
const [selectedItem, setSelectedItem] = useState(selectedItemName);
switch (item) {
case item:
setSelectedItem({
...selectedItemName,
selectボタンを直接作成
buttonラベルを使用してselectボタンを直接作成しています.必要なことは次のとおりです.
選択可能な条件(dropdown item)入力ボタン
上下切替アイコン(isOpenに依存)
dropdown itemを選択すると、ボタンが初期化されます.一度に1つのボタンだけを開く
Active効果:border,shadow dropdown item接続api を選択
カテゴリが選択されていない場合は、を無効にします.
総時間、価格、開設日、繰り返し視聴時間、質疑応答時間によって、ドロップダウンメニューごとに異なります.
<SortingBtn>총 소요시간</SortingBtn>
<SortingBtn>가격</SortingBtn>
<SortingBtn>...</SortingBtn>
<SortingBtn>총 소요시간</SortingBtn>
こうやっていちいち入れたかったのですが、下のdropdownメニューが出てくるのが違うので、ボタン標準と下のdropdownメニュー名をそれぞれ対象に管理することにしました.SortingBox
return (
<div>
{sortingCriteria.map((criteria) => (
<SortingBtn
key={criteria}
value={criteria}
dropListName={dropListName}
onClickOpenSorting={handleOpenSorting}
isOpen={isOpen}
onClickSortingItem={handleClickSortingItem}
isSelected={isSelected}
selectedItem={selectedItem}
criteria={criteria}
>
{criteria}
</SortingBtn>
))}
</div>
);
}
SortingBtn(各selectボタン)
interface SortingBtnProps {
value: sortingType;
children: React.ReactNode;
dropListName: IDropListName;
selectedItem: ISelectedItemName;
isOpen: ISorting;
isSelected: ISorting;
onClickOpenSorting: (criterial: sortingType) => void;
onClickSortingItem: (value: sortingType, item: string) => void;
criteria: sortingType;
}
...
function SortingBtn({
onClickOpenSorting,
onClickSortingItem,
isOpen,
isSelected,
dropListName,
selectedItem,
value,
criteria,
}: SortingBtnProps) {
return (
<StyledRoot onClick={() => onClickOpenSorting(criteria)}>
<BtnTextWrapper>
<CriteriaItem color={colors.gray6}>{value}</CriteriaItem>
{isSelected[value] && (
<>
<CriteriaItem>|</CriteriaItem>
<CriteriaItem color={colors.mainBlue}>{selectedItem[value]}</CriteriaItem>
</>
)}
</BtnTextWrapper>
{isOpen[value] ? <ArrowUp /> : <ArrowDown />}
{isOpen[value] && (
<DropDownBox>
{dropListName[value].map((item) => (
<DropDownItem key={item} onClick={() => onClickSortingItem(value, item)}>
{item}
</DropDownItem>
))}
</DropDownBox>
)}
</StyledRoot>
);
}
1.管理ドロップダウンリストオープン:isOpen
//isOpen 객체의 type정의
export interface ISorting {
[key: string]: boolean;
}
1つのドロップダウンメニューが開いている場合、他のは閉じなければなりません.1回に複数を管理します.
=>オブジェクトに「開くかどうか」(isOpen)ドロップダウンリストを入れます.ex){「定期視聴時間」:true,...}
isOpenオブジェクトを作成するには、forEach文をsortingCriteria配列として使用してfalseの値を持つオブジェクトを作成します.
const sortingObject: ISorting = {};
sortingCriteria.forEach((element) => (sortingObject[element] = false));
const [isOpen, setIsOpen] = useState(sortingObject);
isOpen state로 관리한다.
기본 값으로 들어가는 객체는 다음과 같다.
{ "총 소요시간": false,
"가격": false,
"개설일": false,
"반복시청 기간": false,
"질의응답 시간": false,
}
const handleOpenSorting = (criteria: sortingType) => {switch (criteria) {
case criteria:
setIsOpen({
...sortingObject,
[criteria]: !isOpen[criteria],
});
break;
}
};
버튼 클릭 시, 버튼의 기준(sortingCriteria의 요소)을 가져와서 switch문에서 처리
각각의 case마다 선택한 기준을 제외하곤 모두 false로 바꿔주고(sortingObject는 isOpen의 default값으로 들어간 객체임. 이걸 사용했음.)
선택된기준을 key로 하는 value는 반대 값으로 바꿔준다.
### 2. 드랍다운 아이템 클릭시 값 넣기: selectedItem
### 3. 한 버튼만 셀렉트 할 수 있음 (중복 선택 불가): isSelected
export type sortingType=「総所要時間」|「価格」|「開設日」|「定期視聴時間」|「質疑応答時間」;//dropdownドロップダウン・リスト・タイプの定義
export type IDropListName = {
[key in sortingType]: string[];
};
-> **모두 한 객체에 담아 관리하기**
const isSelectedObject: ISorting = {};const selectedItemName: ISelectedItemName = {};
sortingCriteria.forEach((element) => (isSelectedObject[element] = false));
sortingCriteria.forEach((element) => (selectedItemName[element] = ""));
const [isSelected, setIsSelected] = useState(isSelectedObject);
const [selectedItem, setSelectedItem] = useState(selectedItemName);
- 선택된 기준의 경우만 무엇이 선택되었는지 버튼 안에 표시되어야함.
중복 선택이 안되기 때문에 isOpen처럼 isSelected도 객체로.. 한번에 관리한다.
초기값은 모두 false.
- 중복 정렬기능이 없기 때문에 한 곳에서 선택했으면 나머지는 초기화되어야함
어떤 기준의 어떤 기준 목록을 선택했는지 저장 필요 ex){"가격": "높은 순", ...} 초기값은 모두 빈 문자열
- isOpen과 같이 정렬 기준배열을 forEach문으로
const handleClickSortingItem = (value: sortingType, item: string) => {switch (item) {
case item:
setSelectedItem({
...selectedItemName,
[value]: item,
});
setIsSelected({
...isSelectedObject,
[value]: true,
});
break;
}
};
- 드랍다운 아이템을 클릭하면 어떤 기준을 선택했고, 그 기준(value)의 어떤 목록(item)을 선택했는지 받아온다.
- item이 '긴 순서' '짧은 순서'로 겹치는 경우가 있긴 한데 받아오는 value가 달라서 잘 작동되는 것 같다.
- 어떤 item이 선택되었는지 selectedItemd에 저장하고, 나머지는 빈 문자열로 초기화
- 어떤 기준(value)이 선택되었는지 true로 바꾸고 나머진 false로 초기화
typescript를 배운지 1개월도 되지 않은 상태로 프로젝트 진행중이라 얼렁뚱땅 한 것 같은데, 다행히 잘 돌아가는 걸 보면 이상은 없는 것 같다.
앱잼이 끝나면 typescript개념을 다시 익히면서 차근차근 배우고 어떻게 효율적인 코드를 작성할 수 있을지 고민해보면 좋을 것 같다.
Reference
この問題について(APPJAM]タイプスクリプトによる選択ボタン機能), 我々は、より多くの情報をここで見つけました https://velog.io/@mogamogua/SOPTAPPJAM을-거치며-1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol