Victory-native: Victory chart re-rendering strangely in Expo 39

Created on 16 Oct 2020  路  9Comments  路  Source: FormidableLabs/victory-native

Bugs and Questions

Checklist

  • [X] This is a victory-native specific issue. (Issues that _also_ appear in victory should be opened here)

  • [X] I have read through the FAQ and Guides before asking a question

  • [X] I am using the latest version of victory-native

  • [X] I have checked to make sure that my versions of react-native and react-native-svg are compatible with this version of victory-native. Read about version requirements

  • [X] I've searched open issues to make sure I'm not opening a duplicate issue

The Problem

We recently upgraded our expo app from Expo 37 to Expo 39. Everything seems to work fine except for a strange issue with Victory charts. We visualize some data in a victory chart where the user can change the time range to one of the preset options from a picker. The initial render of the chart is fine. However the first two selections of the time range picker have no effect on the chart. Starting from the third selection, the chart re-renders, but it renders with the range picked from two selections ago (the first selection by the user). Each subsequent time range selection results in the chart rendering based on the time range picked two selections before the actual selection. All other React-Native components in the app are behaving normally.

The victory chart used to work very well in Expo 37, and no code except dependency versions has changed.

Reproduction

Versions
victory-native : 35.0.1
react-native : 0.63.2
react-native-svg : 12.1.0

Code Snippet

<VictoryChart
    theme={gainzVictoryTheme}
    domain={domainRange}
    width={chartWidth}
    scale={{ x: "time", y: "linear" }}
    padding={styles.chartsPadding}>
    <VictoryAxis
        dependentAxis={true}
        tickFormat={y => y}
    />
    <VictoryAxis
        label="Date"
        fixLabelOverlap={true}
        tickFormat={x => `${moment(x).format('M/D')}`}
    />
    <VictoryScatter
        size={3}
        data={chartData}
    />
    <VictoryLine
        interpolation="linear"
        data={chartData}
    />
</VictoryChart>

Most helpful comment

Hi folks! Apologies for the delay. We introduced a bug in [email protected] while we were updating some caching logic. It was causing state to get out of sync. It was fixed in [email protected]. We're using ^ version ranges for victory deps in victory-native so you might have picked up the version with the regression. The latest version of victory-native pins victory deps later than the offending version. Please give it a shot and let me know if it helps.

All 9 comments

@saharshsingh I'm seeing the same issue. Re-renders only occur after the third state change. Did you find any solution to this?

I'm seeing the same issue [3]

We're having the exact same issue. State updates seem to be two steps behind.

Reproduction

Versions
victory-native : 35.0.1
react-native : 0.63.2
react-native-svg : 12.1.0
expo: 39.0.2

Code snippet

import React, { FC, useState } from "react"
import { View } from "react-native"
import {
  VictoryBar,
  VictoryChart,
  VictoryLine,
  VictoryScatter,
  VictoryVoronoiContainer,
} from "victory-native"
const data = [
  { x: 0, y: 0.032 },
  { x: 1, y: 0.035 },
  { x: 2, y: 0.034 },
  { x: 3, y: 0.036 },
  { x: 4, y: 0.038 },
  { x: 5, y: 0.04 },
  { x: 6, y: 0.041 },
  { x: 7, y: 0.042 },
  { x: 8, y: 0.043 },
  { x: 9, y: 0.045 },
  { x: 10, y: 0.05 },
  { x: 11, y: 0.055 },
]

const highestValue = data.reduce(
  (prev, current) => (current.y > prev ? current.y : prev),
  0
)
export const LineChart: FC = () => {
  const [activeIndex, setActive] = useState(null)
  const scatterData = activeIndex !== null ? [data[activeIndex]] : []
  return (
    <View>
      <VictoryChart
        containerComponent={
          <VictoryVoronoiContainer
            onActivated={(points) => {
              setActive(points[0].eventKey)
            }}
            voronoiBlacklist={["scatter", "line"]}
          />
        }
      >
        <VictoryLine name="line" interpolation="natural" data={data} />
        <VictoryBar
          name="bar"
          barRatio={1}
          data={data.map((d) => ({ x: d.x, y: highestValue }))}
          style={{
            data: {
              opacity: ({ active }) => (active ? 0.6 : 0.2),
            },
          }}
        ></VictoryBar>
        <VictoryScatter name="scatter" data={scatterData}></VictoryScatter>
      </VictoryChart>
    </View>
  )
}

In the example, the scatter should be on the same position as the highlighted bar.

IMG_AFA4576EE5DB-1

Same... spent a day troubleshooting before finding this issue. 馃槙

Hello guys I temporarily solved this problem by going back to version 33.0.0

@saharshsingh I'm seeing this as well! Wild!

Hello guys I temporarily solved this problem by going back to version 33.0.0

Thanks for this workaround. Worked for me as well.

Hi folks! Apologies for the delay. We introduced a bug in [email protected] while we were updating some caching logic. It was causing state to get out of sync. It was fixed in [email protected]. We're using ^ version ranges for victory deps in victory-native so you might have picked up the version with the regression. The latest version of victory-native pins victory deps later than the offending version. Please give it a shot and let me know if it helps.

Thanks for the update @boygirl ! Verified that the bug is fixed in version ^35.3.0.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matejkriz picture matejkriz  路  3Comments

xkawi picture xkawi  路  4Comments

xinhash picture xinhash  路  4Comments

ChrisGatzo picture ChrisGatzo  路  3Comments

WhyX picture WhyX  路  6Comments