ViewAlarms 组件处理选择以进入“编辑”模式,用户单击卡以选择将其删除。但是,更改 Alarm.selected 属性似乎不会更新警报卡,除非 AlarmCard 的子级之一被更新,例如切换开关,然后 AlarmCard 显示它已被选择。
ViewAlarms.jsx
function AlarmsViewScreen({ navigation }) {
const { theme, setTheme } = useTheme();
styles = {
primaryColor: theme,
};
const [alarms, setAlarms] = useState([]);
const addAlarm = (newAlarm) => {
setAlarms([...alarms, newAlarm]);
};
const selectAlarm = (alarm) => {
alarm.selected = true;
setMode("editing");
setAlarms[alarms];
};
const [mode, setMode] = useState("viewing");
const onTapAlarm = (alarm) => {
if (mode == "editing") {
selectAlarm(alarm);
} else {
}
};
return (
<View style={{ flex: 1, backgroundColor: "#242424" }}>
<StatusBar translucent={true} />
<Text
style={{
fontSize: 32,
paddingTop: 50,
alignSelf: "center",
color: "#F8E5EE",
fontFamily: "bold",
}}
>
Alarms
</Text>
<Image
source={require("../assets/noalarms.png")}
style={
alarms.length == 0
? { alignSelf: "center", marginTop: 150 }
: { display: "none" }
}
/>
<ScrollView style={{ flex: 1 }}>
{alarms.map((alarm, index) => (
<TouchableOpacity
activeOpacity={0.8}
onLongPress={() => {
selectAlarm(alarm);
}}
onPress={() => {
onTapAlarm(alarm);
}}
>
<AlarmCard mode={mode} alarm={alarm} />
</TouchableOpacity>
))}
</ScrollView>
<TouchableOpacity
style={{
position: "absolute",
bottom: 0,
alignSelf: "center",
margin: 20,
}}
>
<Pressable
onPress={() => {
addAlarm({
selected: false,
alarmName: "Fajr",
alarmTime: "5:40",
M: "AM",
On: true,
Days: ["s1", "m"],
});
}}
>
<View
style={{ flex: 1, justifyContent: "center", alignItems: "center" }}
>
<Image
source={require("../assets/newalarm.png")}
style={{ tintColor: styles.primaryColor, resizeMode: "contain" }}
/>
<Image
source={require("../assets/plus.png")}
style={{ position: "absolute" }}
/>
</View>
</Pressable>
</TouchableOpacity>
</View>
);
}
报警卡.jsx
export const AlarmCard = ({ mode, alarm }) => {
console.log(alarm);
const images = {
selected: require("../assets/selected.png"),
notselected: require("../assets/notselected.png"),
};
const { theme, setTheme } = useTheme();
const [days, setDays] = useState([
{ fri: { display: "F", on: false } },
{ sat: { display: "S", on: true } },
{ sun: { display: "S", on: false } },
{ mon: { display: "M", on: false } },
{ tue: { display: "T", on: false } },
{ wed: { display: "W", on: true } },
{ thu: { display: "T", on: false } },
]);
const index_to_day = ["fri", "sat", "sun", "mon", "tue", "wed", "thu"];
const toggleDay = (index) => {
const updated = [...days];
updated[index][index_to_day[index]].on = updated[index][index_to_day[index]]
.on
? false
: true;
setDays(updated);
};
const [on, setOn] = useState(true);
const toggleSwitch = () => {
const off = on ? false : true;
setOn(off);
};
return (
<View>
<View
style={{
backgroundColor: "#535353",
width: "90%",
height: 240,
margin: "5%",
borderRadius: 20,
}}
>
<Text
style={{
fontSize: 28,
fontFamily: "bold",
color: theme,
margin: 20,
marginBottom: 10,
}}
>
{alarm.alarmName}
</Text>
<View style={{ flexDirection: "row" }}>
<Text
style={{
fontSize: 100,
fontFamily: "bold",
color: "#F8E5EE",
marginHorizontal: 15,
}}
>
{alarm.alarmTime}
</Text>
<Switch
trackColor={{ false: "#838383", true: theme }}
thumbColor={"#F8E5EE"}
onValueChange={toggleSwitch}
value={on}
style={{
marginLeft: 80,
transform: [{ scaleX: 2 }, { scaleY: 2 }],
}}
/>
</View>
<View
style={
mode == "editing"
? {
position: "absolute",
right: 0,
marginRight: 20,
marginTop: 20,
}
: { display: "none" }
}
>
<Image
source={alarm.selected ? images["selected"] : images["notselected"]}
tintColor={alarm.selected ? theme : "#F8E5EE"}
/>
</View>
<View
style={{
backgroundColor: "#838383",
width: "100%",
height: "25%",
borderBottomLeftRadius: 20,
borderBottomRightRadius: 20,
position: "absolute",
bottom: 0,
}}
>
<View style={{ flex: 1, flexDirection: "row", marginHorizontal: 10 }}>
{days.map((day, index) => (
<Pressable
onPress={() => {
toggleDay(index);
}}
key={index}
style={{
marginHorizontal: 5,
marginTop: 13,
borderRadius: 5,
borderColor: theme,
borderWidth: 2,
width: 32,
height: 32,
backgroundColor: day[index_to_day[index]].on
? theme
: "transparent",
alignItems: "center",
}}
>
<Text
style={{ fontFamily: "bold", fontSize: 24, color: "#F8E5EE" }}
>
{day[index_to_day[index]].display}
</Text>
</Pressable>
))}
</View>
</View>
</View>
</View>
);
};
我尝试使用 useEffect 但它不起作用并且 console.log(alarm) ** 不会被调用,除非 AlarmCard 的某些子项被更新,例如拨动开关
const toggleDay = index => setDays( old => {
const updated = [...old]
const [ key, val ] = Object.entries( updated[ index ] )[ 0 ]
val.on = !val.on
updated[ index ] = { [key]:val }
return updated
} )