BugiDev / react-native-calendar-strip

Easy to use and visually stunning calendar component for React Native.
MIT License
951 stars 326 forks source link

Header displays wrong month when selectedDate set to Today #203

Closed nirmaldalmia closed 4 years ago

nirmaldalmia commented 4 years ago

Hi! I want to use the calendar strip as a date picker with the default selected date as today. Here's my code.

        <CalendarStrip
        ref={"calendarStrip"}
                style={styles.strip}
        scrollable={true}
        useIsoWeekday={true}
                //startingDate={new Date()}
                selectedDate={new Date()}
                onDateSelected={(date) =>
                    console.log("Selected date is: ", getDateYYYYMMDD(new Date(date)))
        }
        updateWeek={true}
                daySelectionAnimation={{
                    type: "background",
                    highlightColor: COLORS.primaryBlue,
                }}
                highlightDateNameStyle={{
                   color: COLORS.white,
                }}
        highlightDateNumberStyle={{ color: COLORS.white }}
        />

As shown above, I'm passing a new Date() as the default selectedDate. The selection happens but the month name that is displayed on top is wrong. The dates and days are displayed correctly but the month is wrong. When I scroll to the next set of dates, it corrects itself. Below is a gif of what's happening. The date when this was recorded is 19-06-2020 which reflects as the selected date but the month is shown as December 2019. raw__storage_emulated_0_Download_ezgif com-video-to-gif

Issue seems to similar to this one: #27 . Tried the solutions posted there but it didn't work.

Any help in fixing the issue is much appreciated!

peacechen commented 4 years ago

Thanks for posting your code snippet. I tested it in the example project in this repo and it renders the correct month. I noticed that it briefly flashed December 2019 before updating itself to June 2020. That could be related to the issue you're seeing.

What device are you seeing this behavior on? Please try your code in the example app in this repo. It's an Expo project and is easy to start up. Alternatively, create a Snack that reproduces the behavior.

Edit: I tested the example app with your props on both iOS and Android, and both are working identically.

amidulanjana commented 4 years ago

I am having the same issue. Did you able to solve this

nirmaldalmia commented 4 years ago

@peacechen I tried running the same code on snack and it seems to be working fine on expo projects but I'm running it in a project intialized with react-native cli. Could you please check with a native project?

@amilaDulanjana are you running in an expo project or a native project?

peacechen commented 4 years ago

I created a new app using create-react-native-app, choosing the unmanaged (non-Expo) configuration. It behaves the same as the Expo sample app. The header flashes December 2019 briefly and updates itself to June. What device/OS are you seeing this on?

nirmaldalmia commented 4 years ago

@peacechen the problem occurs on projects initialized with react-native init. I have tried the same in a fresh project too and the problem still exists. Could you please try the code in a project initialized with react-native init? Alternatively I also have a boilerplate if you wanna use one. You clone this repo and install the library to try out.

peacechen commented 4 years ago

I created a new project with react-native init and it works properly on Android. I haven't tested on iOS yet, but from other experiments I expect it to behave the same since this is a purely Javascript library.

I also cloned your react-native-boilerplate repo, installed react-native-calendar-strip, and it works properly as well. Please post a full project that reproduces the behavior, along with details about your dev environment, tool versions (node, react-native CLI, etc...). If it's not the app code, the only difference must be the build system or mobile OS.

nirmaldalmia commented 4 years ago

Hey @peacechen I've tried with two different devices.

  1. Pixel 2 emulator running API 28 (Oreo)
  2. Physical device - OnePlus 6 running Android 10 Both devices still exhibit the issue.

A sample project reproducing the issue: GitHub repo

Here is the environment info of the project:

System:
    OS: Windows 10 10.0.18362
    CPU: (4) x64 Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz
    Memory: 6.73 GB / 15.87 GB
  Binaries:
    Node: 10.16.0 - C:\Program Files\nodejs\node.EXE
    Yarn: Not Found
    npm: 6.14.4 - C:\Program Files\nodejs\npm.CMD
    Watchman: Not Found
  SDKs:
    Android SDK: Not Found
  IDEs:
    Android Studio: Version  3.5.0.0 AI-191.8026.42.35.6010548
  Languages:
    Java: 1.8.0_144
    Python: 3.8.3
  npmPackages:
    @react-native-community/cli: 2.0.1
    react: 16.11.0 => 16.11.0
    react-native: 0.62.2 => 0.62.2
  npmGlobalPackages:
    *react-native*: Not Found
peacechen commented 4 years ago

Thanks @nirmaldalmia for the repro code. Using your sample app, I tracked the bug to onLayout firing multiple times and overwriting the weekStart/EndDate props used by the header. It's puzzling that yours recreates the issue, but the fresh one I created with react-native init did not.

Please test this by pointing to this repo directly in package.json. Run npm install after changing it. I'll publish a new version when you've confirmed this fix.

  "dependencies": {
    "react-native-calendar-strip": "https://github.com/BugiDev/react-native-calendar-strip",
    ...
  }
nirmaldalmia commented 4 years ago

@peacechen thank you so much for the prompt replies and the fix but unfortunately the problem still isn't fixed. You can find the updated code on the same repo.

Also, the problem seems to exist only when scrollable is set to true. Commenting out that property fixes the bug.

peacechen commented 4 years ago

This was very confusing because I saw the code running properly when editing RNCS source directly in node_modules. I suspected a stale cache because the breakpoints were offset and didn't reflect the context and variables where they hit. It works properly after clearing the cache. Here's the steps I used:

  1. Delete node_modules.
  2. npm install
  3. npm start -- --reset-cache
  4. Break out of that after it starts the packager: Ctrl-C.
  5. react-native run-android

The --reset-cache flag requires @react-native-community/cli-tools:

npm install @react-native-community/cli-tools --global

nirmaldalmia commented 4 years ago

Hey @peacechen the problem seems to be resolved now. Although it's still buggy on my laptop (I wonder why that is, but I've come across a similar caching issue before with another library on my laptop), I asked a friend to try running the project and he can see the correct month now. Thank you for the fix!

peacechen commented 4 years ago

Glad to hear it worked. Was npm start -- --reset-cache unable to clear the cache on your laptop?

I published a new version on npm. Hopefully that takes care of caching issues for you.

nirmaldalmia commented 4 years ago

Sure. I'll try again. Thanks for the help :)

bhaskardabhi commented 4 years ago

I am still facing the same issue.

Following is my dependencies:

"native-base": "^2.13.12",
"react": "16.11.0",
"react-native": "0.62.2",
"react-native-calendar-strip": "^2.0.8",

Following is my code:


state = {
        items: null,
        iStart: 0,
        iLimit: 10,
        loading: false,
        currentDate: moment(),
        hasMore: true,
        sKeyword: null,
    };

<View style={{padding: 5, flex: 1,paddingBottom: 80}}>
    <CalendarStrip 
        scrollable
        selectedDate={this.state.currentDate}
        onDateSelected={(selectedDate) => {
            that.setCurrentDate(selectedDate);
        }}
        highlightDateNameStyle={{
            fontWeight: 'bold'
        }}
        highlightDateNumberStyle={{
            fontWeight: 'bold',
        }}
        style={{
            height: 80
        }} dateNumberStyle={{
            fontWeight: 'normal'
        }} />
    <View style={{paddingBottom: 80}}>
        <FlatList
            data={items}
            onEndReached={this.fetchItems}
            onRefresh={this.onRefresh}
            refreshing={this.state.refreshing}
            onEndReachedThreshold={1}
            onMomentumScrollBegin={() => { 
                this.onEndReachedCalledDuringMomentum = false; 
            }}
            ListEmptyComponent={() => (
                <View>
                    {this.state.items !== null && <View style={{
                            justifyContent: 'center',
                            flex: 1,
                            marginTop: 50,
                            marginBottom: 50
                        }}>
                        <Text style={{ textAlign: 'center' }}>No items for the day.</Text>
                    </View>}
                </View>
            )}
            renderItem={({ item, index }) => {
                return <Item item={item} />
            }}
        />
    </View>
</View>