software-mansion / react-native-svg

SVG library for React Native, React Native Web, and plain React web projects.
MIT License
7.42k stars 1.12k forks source link

V8 -> V9 Breaking Change: setNativeProps #1010

Closed petrogad closed 4 years ago

petrogad commented 5 years ago

I recently upgraded from 8.0.11 to 9.4 and found there is a breaking change with how setNativeProps works.

You can no longer use a reference to update a path in 9.4 as the redraw will not occur. Is there an issue tracking this?

Note, this is still working on 8.0.11

IE


class MyComponent extends Component {
    componentDidMount() {
        setTimeout(() => {
            const myPercent = formatPercentage(0.5);
            this._myPath.setNativeProps({
                d: generateSectionFromPercentage(myPercent, 80)
            });
        }, 2500);
    }
    render() {
        const myPercent = formatPercentage(0.1);
        const pathString = generateSectionFromPercentage(myPercent, 80);

        return (
            <Svg width={160} height={160} viewBox="0 0 80 80">
                <Defs>
                    <ClipPath id="successfulClippingPath">
                        <Path
                            ref={ref => {
                                this._myPath = ref;
                            }}
                            d={pathString}
                            fill={"#FFF"}
                        />
                    </ClipPath>
                </Defs>
                <Use
                    fillRule="evenodd"
                    fill={"none"}
                    href={"#hexagon"}
                    clipPath="url(#successfulClippingPath)"
                    stroke={"#06E6FA"}
                    strokeWidth="7"
                />
            </Svg>
        );
    }
}
msand commented 4 years ago

At least this seems to work correctly in the latest version. So seems this has been fixed now.

App.js

import React, {Component} from 'react';
import {View, StyleSheet} from 'react-native';
import Svg, {Defs, ClipPath, Path, Polygon, Use} from 'react-native-svg';

const getPath = (a, b) => `M 0 0 L ${a} 0 ${a} ${b}`;

class Test extends Component {
  componentDidMount() {
    setTimeout(() => {
      this._myPath.setNativeProps({
        d: getPath(50, 80),
      });
    }, 2500);
  }
  render() {
    return (
      <Svg width={160} height={160} viewBox="0 0 80 80">
        <Defs>
          <ClipPath id="successfulClippingPath">
            <Path
              ref={ref => {
                this._myPath = ref;
              }}
              d={getPath(10, 80)}
              fill={'#FFF'}
            />
          </ClipPath>
          <Polygon
            id="hexagon"
            points="30,15 22.5,28 7.5,28 0,15 7.5,2 22.5,2"
            fill="lime"
            stroke="purple"
            strokeWidth="1"
          />
        </Defs>
        <Use
          fillRule="evenodd"
          fill={'none'}
          href={'#hexagon'}
          clipPath="url(#successfulClippingPath)"
          stroke={'#06E6FA'}
          strokeWidth="7"
        />
      </Svg>
    );
  }
}

export default () => (
  <View style={styles.container}>
    <Test />
  </View>
);

const styles = StyleSheet.create({
  container: {
    backgroundColor: 'black',
    justifyContent: 'center',
    alignItems: 'center',
    flex: 1,
  },
});
mikeaustin commented 4 years ago

I don't see setNativeProps as a property on shapes such as Ellipse. I'm using react-native-web, so I can use event.target I guess. I just wanted to use RN APIs as much as possible.

xcarpentier commented 4 years ago

@mikeaustin

I don't see setNativeProps as a property on shapes such as Ellipse. I'm using react-native-web, so I can use event.target I guess. I just wanted to use RN APIs as much as possible.

Did you find a way to make it? I'm using a dirty trick to do this:

this.mask.current._touchableNode.setAttribute('d', d)

See full example in this lib: rn-tourguide

  1. https://github.com/xcarpentier/rn-tourguide/blob/master/src/components/SvgMask.tsx#L63
  2. https://github.com/xcarpentier/rn-tourguide/blob/master/src/components/SvgMask.tsx#L122
  3. https://github.com/xcarpentier/rn-tourguide/blob/master/src/components/AnimatedPath.tsx#L9