使用componentDidUpdate动态更改React组件中的选定日期

时间:2019-08-14 21:36:27

标签: react-native react-native-calendars

每次用户导航到日历屏幕时,我都需要将selectedDay更改为当前日期。

我将所选日期设置为今天,并且已经可以检测到用户何时访问屏幕,但是即使更改状态或强制更新,日历也不会移动到我设置为所选日期的日期。

  componentDidUpdate = async (prevProps) => {
    if (prevProps.isFocused !== this.props.isFocused && this.props.isFocused) {
      this.forceUpdate()
    }
  }

<Agenda
  items={events}
  pastScrollRange={50}
  futureScrollRange={50}
  onDayPress={this.setCurrentDate}
  loadItemsForMonth={this.loadItems}
  renderItem={this.renderItem}
  renderEmptyDate={this.renderEmptyDate}
  rowHasChanged={this.rowHasChanged}
  selected={this.state.today}
/>

使用forceUpdate或更改某些任意状态,日历将停留在当前选定的日期。我希望它可以回到今天。

1 个答案:

答案 0 :(得分:2)

您可以设置议程组件的参考

 ref={ref => {
      this.agenda = ref;
 }}

然后在componentDidUpdate上,通过调用Agenda组件的onDayChange函数将日期更改为当前日期

if (prevProps.isFocused !== this.props.isFocused) {
    setTimeout(() => {
    this.agenda.onDayChange(this.state.today);
}, 500);

See App Preview

完整代码

import React, { Component } from "react";
import { Agenda } from "react-native-calendars";
import { Text, View, StyleSheet } from "react-native";
import { withNavigationFocus } from "react-navigation";

class Home extends Component {
  constructor(props) {
    super(props);

    this.state = {
      items: {},
      today: new Date().toISOString().split("T")[0]
    };
  }

  componentDidUpdate(prevProps) {
    if (prevProps.isFocused !== this.props.isFocused) {
      setTimeout(() => {
        this.agenda.onDayChange(this.state.today);
      }, 500);
    }
  }

  render() {
    return (
      <View style={{ flex: 1 }}>
        <Text
          style={{ padding: 30, fontWeight: "bold", textAlign: "center" }}
          onPress={() => this.props.navigation.navigate("NewScreen")}
        >
          Go To Next Screen
        </Text>
        <Agenda
          items={this.state.items}
          loadItemsForMonth={this.loadItems.bind(this)}
          selected={this.state.today}
          renderItem={this.renderItem.bind(this)}
          renderEmptyDate={this.renderEmptyDate.bind(this)}
          rowHasChanged={this.rowHasChanged.bind(this)}
          onDayPress={day => {
            console.log("selected day", day);
          }}
          ref={ref => {
            this.agenda = ref;
          }}
        />
      </View>
    );
  }

  loadItems(day) {
    setTimeout(() => {
      for (let i = -15; i < 85; i++) {
        const time = day.timestamp + i * 24 * 60 * 60 * 1000;
        const strTime = this.timeToString(time);
        if (!this.state.items[strTime]) {
          this.state.items[strTime] = [];
          const numItems = Math.floor(Math.random() * 5);
          for (let j = 0; j < numItems; j++) {
            this.state.items[strTime].push({
              name: "Item for " + strTime,
              height: Math.max(50, Math.floor(Math.random() * 150))
            });
          }
        }
      }
      //console.log(this.state.items);
      const newItems = {};
      Object.keys(this.state.items).forEach(key => {
        newItems[key] = this.state.items[key];
      });
      this.setState({
        items: newItems
      });
    }, 1000);
    // console.log(`Load Items for ${day.year}-${day.month}`);
  }

  renderItem(item) {
    return (
      <View style={[styles.item, { height: item.height }]}>
        <Text>{item.name}</Text>
      </View>
    );
  }

  renderEmptyDate() {
    return (
      <View style={styles.emptyDate}>
        <Text>This is empty date!</Text>
      </View>
    );
  }

  rowHasChanged(r1, r2) {
    return r1.name !== r2.name;
  }

  timeToString(time) {
    const date = new Date(time);
    return date.toISOString().split("T")[0];
  }
}

const styles = StyleSheet.create({
  item: {
    backgroundColor: "white",
    flex: 1,
    borderRadius: 5,
    padding: 10,
    marginRight: 10,
    marginTop: 17
  },
  emptyDate: {
    height: 15,
    flex: 1,
    paddingTop: 30
  }
});

export default withNavigationFocus(Home);