您好,我实际上是在构建一个记事应用程序,您可以在其中将一些记事添加到日历中的特定日期。
我在日历中使用了wix-agenda组件。 单击灰色复选框时,我更新了要检查的项目的状态,但该状态未得到更新。 当我再次将文件保存在编辑器中(使用Hotload)时,组件会更新,并且复选框显示为黄色。有人提示吗?
const SCREEN_WIDTH = Dimensions.get('window').width;
const SCREEN_HEIGHT = Dimensions.get('window').height;
const customAnimation = {
duration: 100,
create: {
type: LayoutAnimation.Types.linear,
property: LayoutAnimation.Properties.opacity,
},
update: {
type: LayoutAnimation.Types.linear,
}
};
class CalendarScreen extends Component {
constructor(props) {
super(props);
this.state = {
items: {
'2018-08-20': [
{key: '2018-08-20', name: 'Test', checked: true },
{key: '2018-08-20', name: 'Test', checked: false },
{key: '2018-08-20', name: 'Test', checked: false },
],
'2018-08-21': [
],
'2018-08-22': [
{key: '2018-08-22', name: 'Test!', checked: true },
{key: '2018-08-22', name: 'Test', checked: false },
{key: '2018-08-22', name: 'Test', checked: true },
],
},
reason: '',
itemsOld: {},
isModalVisible: false,
noteDate: new Date(),
noteText: '',
isLoading: false
};
}
/* async componentWillMount() {
let notes = await AsyncStorage.getItem('notes');
if (!_.isNull(notes)) {
console.log('>>>>>>>>'+ notes)
this.setState({ items: notes, isLoading: false });
console.log("###### MOUNT #######");
console.log("ITEMS: >>> "+ this.state);
}
}*/
componentWillUpdate() {
LayoutAnimation.linear();
LayoutAnimation.configureNext(customAnimation);
}
/*async componentWillUnmount() {
await AsyncStorage.setItem('notes', JSON.stringify(this.state.items));
}*/
onToastClose(reason) {
this.setState({ reason });
if (reason === 'user') {
this.setState({ items: this.state.itemsOld });
}
}
setDate(newDate) {
newDate.setDate(newDate.getDate()+1);
date = newDate.toISOString().split('T')[0];
this.setState({ noteDate: date });
}
loadItems(day) {
// console.log(`Load Items for ${day.year}-${day.month}`);
}
addNote() {
oldState = { ...this.state.items };
arrayToPush = oldState[this.state.noteDate];
if (_.isNil(arrayToPush)) {
arrayToPush = [];
}
arrayToPush.push({key: this.state.noteDate, name: this.state.noteText, checked: false });
oldState[this.state.noteDate] = arrayToPush;
this.setState({ items: oldState, noteText: '', isModalVisible: false });
}
removeItem(item) {
//Copy state
oldState = { ...this.state.items };
//Get actual clicked key -> date of note is the key
actualArray = [...this.state.items[item.key]];
// Get the index in the Array with the notes
index = actualArray.indexOf(item);
//remove the object from the array!!
actualArray.splice(index,1);
//Copy previous state
newState = { ...this.state.items };
//Update array with key of clicked element
newState[item.key] = actualArray;
Toast.show({
text: 'Sie haben eine Notiz entfernt!',
buttonText: 'Rückgangig',
duration: 3000,
onClose: this.onToastClose.bind(this)
});
//Update state --- MAGIC!
this.setState({ items: newState, itemsOld: oldState });
}
toggleCheck(item) {
//Get actual clicked key -> date of note is the key
actualArray = [...this.state.items[item.key]];
// Get the index in the Array with the notes
index = actualArray.indexOf(item);
//change the checkmark!!
actualArray[index].checked = !actualArray[index].checked;
//Copy previous state
newState = { ...this.state.items };
//Update array with key of clicked element
newState[item.key] = actualArray;
//Update state --- MAGIC!
this.setState({ items: newState });
}
_toggleModal = () => {
this.setState({ isModalVisible: !this.state.isModalVisible });
}
rowHasChanged(r1, r2) {
return r1.name !== r2.name;
}
timeToString(time) {
const date = new Date(time);
return date.toISOString().split('T')[0];
}
renderDay(day,item) {
if (day) {
return (
<View style={styles.day}>
<Text allowFontScaling={false} style={[styles.dayNum]}>{day.day }</Text>
<Text allowFontScaling={false} style={[styles.dayText]}>{day.text}</Text>
</View>
);
}
return (
<View style={styles.day}/>
);
}
renderEmptyDate() {a
return (
<View style={styles.emptyDate}><Container><Text>This is empty date!</Text></Container></View>
);
}
renderItem(item) {
color = item.checked ? "#F7D23D" : '#ccc';
return (
<Container
style={[styles.item, { height: 70, flexDirection: 'row', alignItems: 'center' }]}
>
<Body style={{ flex: 5 }}>
<Text>{item.name}</Text>
</Body>
<Body style={{ flex: 1 }}>
<MaterialIcons
size={24} name="check-circle" color={color}
style={{ alignSelf: 'center', }}
onPress={() => {
this.toggleCheck(item);
}}
/>
</Body>
</Container>
);
}
render() {
if (this.state.isLoading) {
return <View><Text>Loading...</Text></View>;
}
return (
<Container>
<Header textStyle={{ color: 'white' }}>
<Left >
<Button light transparent style={styles.whiteIcon} onPress={() => this.props.navigation.dispatch(DrawerActions.openDrawer())}>
<Icon name='ios-menu' />
</Button>
</Left>
<Body>
<Title style={styles.headerTextStyle}> KALENDER </Title>
</Body>
<Right>
<Button light transparent>
<Icon name='search' />
</Button>
</Right>
</Header>
<Container>
<Agenda
//https://github.com/wix/react-native-calendars
items={this.state.items}
loadItemsForMonth={this.loadItems.bind(this)}
selected={'2018-08-20'}
renderItem={this.renderItem.bind(this)}
renderEmptyDate={() => {return (<View />);}}
renderEmptyData = {() => {return (<View />);}}
rowHasChanged={this.rowHasChanged.bind(this)}
theme={{ selectedDayBackgroundColor: '#F7D23D', todayTextColor: '#F7D23D', dotColor: '#F7D23D',}}
renderDay={this.renderDay.bind(this)}
/>
<Modal
avoidKeyboard
isVisible={this.state.isModalVisible}
animationType="fade"
onBackdropPress={() => this._toggleModal()}
onBackButtonPress={() => this._toggleModal()}
style={{ justifyContent: 'flex-end'}}
backdropOpacity={0.5}
>
<Card>
<CardItem header>
<Text>Notiz erstellen</Text>
</CardItem>
<CardItem>
<Form style={{ flex: 1}}>
<DatePicker
defaultDate={new Date(2018, 8, 20)}
minimumDate={new Date(2018, 1, 1)}
maximumDate={new Date(2018, 12, 31)}
locale={"de"}
modalTransparent={false}
animationType={"fade"}
androidMode={"default"}
placeHolderText="Datum wählen"
placeHolderTextStyle={{ color: "#d3d3d3" }}
onDateChange={this.setDate.bind(this)}
/>
<Textarea rowSpan={3} placeholder="Notiz" value={this.state.noteText} onChangeText={text => this.setState({ noteText: text })} />
</Form>
</CardItem>
<CardItem footer>
<Left>
</Left>
<Body>
<Button transparent onPress={()=>{this._toggleModal()}}>
<Text>Abbrechen</Text>
</Button>
</Body>
<Right>
<Button transparent onPress={this.addNote.bind(this)}>
<Text>Hinzufügen</Text>
</Button>
</Right>
</CardItem>
</Card>
</Modal>
<Fab
style={{ backgroundColor: '#F7D23D' }}
position="bottomRight"
onPress={() => {
this.setState({ active: !this.state.active });
this._toggleModal();
}}
>
<MaterialIcons size={24} name="add" />
</Fab>
</Container>
</Container>
);
}
//COMPONENT END
}
const styles = StyleSheet.create({
item: {
backgroundColor: 'white',
flex: 1,
borderRadius: 5,
padding: 10,
marginRight: 10,
marginTop: 10
},
emptyDate: {
height: 15,
flex:1,
paddingTop: 30
},
dayNum: {
fontSize: 28,
fontWeight: '200',
color: 'black'
},
dayText: {
fontSize: 14,
fontWeight: '300',
color: 'black',
marginTop: -5,
backgroundColor: 'rgba(0,0,0,0)'
},
day: {
width: 63,
alignItems: 'center',
justifyContent: 'flex-start',
marginTop: 32
},
});
export default CalendarScreen;
主要部分在这里
toggleCheck(item) {
//Get actual clicked key -> date of note is the key
actualArray = [...this.state.items[item.key]];
// Get the index in the Array with the notes
index = actualArray.indexOf(item);
//change the checkmark!!
actualArray[index].checked = !actualArray[index].checked;
//Copy previous state
newState = { ...this.state.items };
//Update array with key of clicked element
newState[item.key] = actualArray;
//Update state --- MAGIC!
this.setState({ items: newState });
}
有什么建议吗?
答案 0 :(得分:1)
在let
方法内声明的局部变量似乎缺少关键字const
和toggleCheck
,导致分配给全局变量而不是回调局部变量—特别是,变量actualArray
,index
和newState
在这些回调的所有调用中都是共享的。
方法setDate
,addNote
,removeItem
和renderItem
中也是如此。
这是解决toggleCheck
的方法:
toggleCheck(item) {
const actualArray = [...this.state.items[item.key]];
const index = actualArray.indexOf(item);
actualArray[index].checked = !actualArray[index].checked;
const newState = { ...this.state.items };
newState[item.key] = actualArray;
this.setState({ items: newState });
}