我正在嘗試更改陣列中元素的活動樣式。如下圖所示 - 當您按下日期時,樣式將更改以在其周圍添加邊框。

到目前為止,我正在努力單獨更改每個元素的布爾狀態并跟蹤當我按下另一個日期時它將活動狀態更改為 false。到目前為止,這是我的代碼:
function Journal() {
const day = new Date().getDay();
const month = new Date().getMonth();
const dayNumber = new Date().getDate();
const [active, setActive] = useState(false);
let [fontsLoaded] = useFonts({
Roboto_400Regular
});
if (!fontsLoaded) {
return <></>;
} else {
return (
<ScrollView>
<CheckInHeader/>
<View style={{margin: 32}}>
<Text style={{fontSize: 18, fontFamily: 'Roboto_400Regular'}}>Today</Text>
<View style={{flexDirection: 'row'}}>
<Text
style={{
fontSize: 14,
fontFamily: 'Roboto_400Regular',
color: '#878787'
}}>{getDay(day)} </Text>
<Text style={{
fontSize: 14,
fontFamily: 'Roboto_400Regular',
color: '#878787'
}}>{getDayNumber(dayNumber)} </Text>
<Text style={{
fontSize: 14,
fontFamily: 'Roboto_400Regular',
color: '#878787'
}}>{getMonth(month)}</Text>
</View>
<JournalEntry/>
<View style={{flexDirection: 'row-reverse', justifyContent: 'space-around', marginTop: 64}}>
{lastSevenDays().map((result, i) => {
return (
<TouchableOpacity
style={[lastSevenDays()[i].active ? {
alignItems: 'center',
borderColor: '#DBDBDB',
borderWidth: 1,
borderRadius: 16,
minWidth: 48,
padding: 8
} : {alignItems: 'center'}]}
onPress={() => {
lastSevenDays()[i].active
}}
>
<Text>{result.day?.slice(0, 3)}</Text>
<Text>{result.dayNumber}</Text>
</TouchableOpacity>
)
})}
</View>
</View>
</ScrollView>
);
}
}
export const lastSevenDays = (): {day: string | undefined, dayNumber: number, month: string | undefined, active: boolean}[] => {
let result = [];
for (let i=0; i<7; i ) {
let d = new Date();
d.setDate(d.getDate() - i);
result.push({day: getDay(d.getDay()), dayNumber: d.getDate(), month: getMonth(d.getMonth()), active: false})
}
return (result);
}
任何關于如何做到這一點的幫助都會很棒!謝謝 :)
uj5u.com熱心網友回復:
我看到兩個主要問題:
- 首先與最佳實踐和代碼可讀性更相關:我認為您不需要在 html 中使用 lastSevenDays().map (甚至多次)。最好將值存盤在陣列中(類似于將實際的 lastSevenDays 函式重命名為 getLastSevenDays,然后使用變數 const lastSevenDays = getLastSevenDays() 并使用該變數。
- 如果您只在活動日使用狀態而不是單獨更改元素的活動狀態,那將是最好的。最簡單的方法是將活動日索引存盤在一個狀態中。
有點像:
const [activeDay, setActiveDay] = useState(); //feel free to default the active day here
...
...
<TouchableOpacity
style={[activeDay === i ? {
alignItems: 'center',
borderColor: '#DBDBDB',
borderWidth: 1,
borderRadius: 16,
minWidth: 48,
padding: 8
}
:
{alignItems: 'center'}
]}
onPress={() => {
setActiveDay(i)
}}>
如果有任何理由避免使用索引,您可以將其替換為日期(在這種情況下,函式應該類似于setActiveDate(result.dayNumber)并且條件將切換到activeDate === result.dayNumber),或者甚至更高級的選項,例如
setActiveDate(`${result.dayNumber}-${result.month}`)
如果你真的需要它。
PS(一些建議):
- 我還建議避免使用如此多的行內樣式(通常不是一個好習慣)。您還可以嘗試classNames - 一個 JavaScript 實用程式,用于有條件地將 classNames 連接在一起。
- 你可以
return null代替return <></>. 此外,您實際上并不需要elsereturn 之前的陳述句(如果它會繼續 if 它將回傳值,所以它自然會停止執行。所以你可以只寫第二個 return 而沒有else)
您還可以稍微改進變數命名(尤其是結果部分)和使用const(fontsLoaded并且result變數不會被重新分配,因此您也可以只使用const它們)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/422628.html
標籤:
