[英]Close accordions on radio button click
我的 React Native 應用程序中有一個來自 galio 框架的手風琴組件。 我用 api 數據填充它。 如果您單擊標題,手風琴將關閉,但我希望它在 select 單選按鈕時關閉。 這是我的代碼:
const Step3 = () => {
const [questions, setQuestions] = useState([]);
const [answers, setAnswers] = useState([]);
const [icon, setIcons] = useState([]);
const [iconColor, setIconsColor] = useState([])
const [refreshing, setRefreshing] = useState(true);
const getQuestions = async () => {
const locale = i18next.language; // TODO: get current locale
const response = await apiStandarts.get(`/questions?locale=${locale}`, {
params: { active: 1, _sortId: [1,2] , _sort: "sortId:ASC"},
});
setRefreshing(false)
setQuestions(response.data);
};
const isOptionSelected = (option) => {
const answer = answers[option.question];
if (answer) {
return option.id == answer.id;
}
return false;
};
const questionIcon = async () => {
const response = await apiStandarts.get(`/commitments-icons`);
setIcons(response.data)
}
const questionIconColor = async () => {
const response = await apiStandarts.get(`/commitments`);
setIconsColor(response.data)
}
const objectMap = (obj, fn) =>
Object.fromEntries(
Object.entries(obj).map(([k, v], i) => [k, fn(v, k, i)])
);
const newAnswers = objectMap(answers, (item) => {
return [item.id, item.description];
});
// useEffect(() => {
// questionIcon();
// }, []);
useEffect(() => {
questionIcon();
getQuestions();
}, []);
const OptionList = (groupOption) => {
return (
groupOption.options.map((item, index) => {
const clickedRadio = () => {
const selectedOption = { [item.question]: { ...item } };
setAnswers({ ...answers, ...selectedOption });
};
let status = isOptionSelected(item) ? true : false;
return (
<Radio
initialValue={status}
label={item.description}
onChange={() => clickedRadio()}
color="rgba(0,0,0,.54)"
radioInnerStyle={{backgroundColor: "#3671a6"}}
labelStyle={ styles.label}
containerStyle={{ width: 300, padding: 5 }}
/>
);
})
);
};
return (
<View style={styles.container}>
<Text style={{ fontWeight: "bold", fontSize: 12, color: "#6B24" }}>
{t("Choose an option/Scroll for more questions")}
</Text>
<FlatList
data={questions}
keyExtractor={(result) => result.id.toString()}
contentContainerStyle={{ padding: 5, paddingBottom: 5 }}
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={getQuestions} />}
renderItem={({ item, index }) => {
const arr = [item.commitments[0].commitment_icon];
const questIcon = arr.filter(i => Boolean(i)).map(id => icon.find(o => o.id === id)?.image?.url);
const imgUrl = APIURL + questIcon;
function iconBgColor(){
let bgColor
switch (item.commitments[0].commitment_icon) {
case 1:
bgColor="#78bad3"
break;
case 3:
bgColor = "#027a95"
break;
case 6:
bgColor = "#027a95"
break;
case 4:
bgColor = '#1fc191'
break;
case 5:
bgColor = '#78bad3'
break;
case 2:
bgColor = "#e4da4d"
break;
case 7:
bgColor = "#1fc191"
break;
default:
bgColor= "#fff"
break;
}
return bgColor;
}
const backgroundColor = iconBgColor(item.commitments[0].commitment_icon)
const data = [
{
title: (<>
<View style={[styles.iconWrapper,{backgroundColor: backgroundColor}]}>
{
imgUrl.indexOf('.svg') > 0 ? <SvgUri uri={APIURL + questIcon} height={20} width={20} style={styles.iconColor}/> : null
}
</View>
<Text style={styles.text}>{item.sortId}.</Text>
<Text style={styles.text} key={item.description}>{item.description}</Text>
</>),
content:<View><OptionList key={item?.question_options.id} options={item?.question_options}></OptionList></View>
},
];
return (
<View style={styles.groupOptions} key={index}>
<Accordion style={styles.accordion} headerStyle={styles.headerStyle} contentStyle={styles.contentStyle} dataArray={data} opened={index} />
</View>
);
}}
/>
</View>
);
};
任何想法如何實現我想要的? 任何答案將不勝感激,謝謝。
您可以為開放索引管理 state 並將其傳遞給 accrodian
你有下一個代碼:
<Accordion
style={styles.accordion}
headerStyle={styles.headerStyle}
contentStyle={styles.contentStyle}
dataArray={data}
opened={index} // here you should have "isAccordionOpen"
/>
並在您的 Step3 組件中處理 state 中的變量。
在這個 function 你應該改變這個變量“isAccordionOpen”
const clickedRadio = () => {
const selectedOption = { [item.question]: { ...item } };
setAnswers({ ...answers, ...selectedOption });
}
正如我在文檔和 Galio 庫中檢查的那樣,在第一個渲染周期之后似乎沒有管理 Accordion 的道具。
我們最初只能在第一次渲染時管理 Accordion。
如果您必須管理它,那么您必須在 Galio 庫代碼中進行更改。
在這里我附上示例代碼庫,希望它可以幫助你。
示例代碼:
import React, { useState } from 'react'
import { View } from 'react-native'
import { Accordion, Block, Checkbox } from 'galio-framework';
const App = () => {
const [openIndex, setOpenIndex] = useState(-1)
const radioClickHandler = (id, status) => {
setOpenIndex(-1)
}
const data = [
{
title: "First Chapter",
content: (
<Checkbox
onChange={radioClickHandler.bind(null, 'first')}
color="primary"
label="Primary Checkbox"
/>
)
},
{
title: "Second Chapter",
content: (
<Checkbox
onChange={radioClickHandler.bind(null, 'second')}
color="primary"
label="Secondary Checkbox"
/>
)
}
]
const onOpen = (prop) => {
setOpenIndex(prop?.title === "First Chapter" ? 0 : 1)
}
return (
<View style={{ flex: 1, justifyContent: 'center' }}>
<Block style={{ height: 200 }}>
<Accordion
dataArray={data}
opened={openIndex}
onAccordionOpen={onOpen}
/>
</Block>
</View>
)
}
export default App
這是管理折疊手風琴組件的庫代碼中的更改。
文件路徑:'node_modules/galio-framework-src-Accordion.js'
添加下面的代碼
const [selected, setSelected] = useState(opened);
useEffect(() => {
setSelected(opened)
}, [opened])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.