Open lc3t35 opened 1 month ago
same problem here, version 14 broke my icons, I workaround using version 13:
"@expo/vector-icons": "^13.0.0"
In version 13, the code seems to be based on a React.Component not a function -> workaround is also working for me. Thank you @geovane7881
hi there! do you have a minimal reproducible example that you can share?
@brentvatne I gave the exact location of the issue (build/createIconSet.js), the previous code @13.0.0 works and the new code @14.0.0 does not work.
The code in @14 returns a class Icon extends React.Component
and uses Icon inside the function which is not correct, the code in 13 (as a component) stores the class in a var _a :
var _a;
const font = { [fontName]: expoAssetId };
const RNVIconComponent = createIconSet(glyphMap, fontName, null, fontStyle);
return _a = class Icon extends React.Component {
constructor() { ...},
...
},
_a.defaultProps = RNVIconComponent.defaultProps,
_a.Button = createIconButtonComponent(_a),
....
_a;
}
This looks like a generated code ... from ts or babel ? It's interesting to know why the @14 code was not generated this way ... Easy to fix, store the class, update the props Button and others, return the modified class ...
Do you really need a reproducible example ?
This is how I fixed this error :
export default function (glyphMap, fontName, expoAssetId, fontStyle) {
const font = { [fontName]: expoAssetId };
const RNVIconComponent = createIconSet(glyphMap, fontName, null, fontStyle);
class Icon extends React.Component {
static defaultProps = RNVIconComponent.defaultProps;
static glyphMap = glyphMap;
static getRawGlyphMap = () => glyphMap;
static getFontFamily = () => fontName;
static loadFont = () => Font.loadAsync(font);
static font = font;
_mounted = false;
_icon;
state = {
fontIsLoaded: Font.isLoaded(fontName),
};
async componentDidMount() {
this._mounted = true;
if (!this.state.fontIsLoaded) {
await Font.loadAsync(font);
/* eslint-disable react/no-did-mount-set-state */
this._mounted && this.setState({ fontIsLoaded: true });
}
}
componentWillUnmount() {
this._mounted = false;
}
setNativeProps(props) {
if (this._icon) {
this._icon.setNativeProps(props);
}
}
render() {
if (__DEV__ && this.props.name && !(this.props.name in glyphMap)) {
console.warn(`"${this.props.name}" is not a valid icon name for family "${fontName}"`);
}
if (!this.state.fontIsLoaded) {
return <Text />;
}
return (<RNVIconComponent ref={(view) => {
this._icon = view;
}} {...this.props}/>);
}
};
Icon.Button = createIconButtonComponent(Icon); // Move this line after the class definition
return Icon;
}
And the patch file @expo+vector-icons+14.0.2.patch
for anybody who has the issue and wants to use 14.0.2 :
diff --git a/node_modules/@expo/vector-icons/build/createIconSet.js b/node_modules/@expo/vector-icons/build/createIconSet.js
index e8e1ec0..41d085a 100644
--- a/node_modules/@expo/vector-icons/build/createIconSet.js
+++ b/node_modules/@expo/vector-icons/build/createIconSet.js
@@ -7,9 +7,9 @@ export { DEFAULT_ICON_COLOR, DEFAULT_ICON_SIZE, } from './vendor/react-native-ve
export default function (glyphMap, fontName, expoAssetId, fontStyle) {
const font = { [fontName]: expoAssetId };
const RNVIconComponent = createIconSet(glyphMap, fontName, null, fontStyle);
- return class Icon extends React.Component {
+
+ class Icon extends React.Component {
static defaultProps = RNVIconComponent.defaultProps;
- static Button = createIconButtonComponent(Icon);
static glyphMap = glyphMap;
static getRawGlyphMap = () => glyphMap;
static getFontFamily = () => fontName;
@@ -18,35 +18,39 @@ export default function (glyphMap, fontName, expoAssetId, fontStyle) {
_mounted = false;
_icon;
state = {
- fontIsLoaded: Font.isLoaded(fontName),
+ fontIsLoaded: Font.isLoaded(fontName),
};
async componentDidMount() {
- this._mounted = true;
- if (!this.state.fontIsLoaded) {
- await Font.loadAsync(font);
- /* eslint-disable react/no-did-mount-set-state */
- this._mounted && this.setState({ fontIsLoaded: true });
- }
+ this._mounted = true;
+ if (!this.state.fontIsLoaded) {
+ await Font.loadAsync(font);
+ /* eslint-disable react/no-did-mount-set-state */
+ this._mounted && this.setState({ fontIsLoaded: true });
+ }
}
componentWillUnmount() {
- this._mounted = false;
+ this._mounted = false;
}
setNativeProps(props) {
- if (this._icon) {
- this._icon.setNativeProps(props);
- }
+ if (this._icon) {
+ this._icon.setNativeProps(props);
+ }
}
render() {
- if (__DEV__ && this.props.name && !(this.props.name in glyphMap)) {
- console.warn(`"${this.props.name}" is not a valid icon name for family "${fontName}"`);
- }
- if (!this.state.fontIsLoaded) {
- return <Text />;
- }
- return (<RNVIconComponent ref={(view) => {
- this._icon = view;
- }} {...this.props}/>);
+ if (__DEV__ && this.props.name && !(this.props.name in glyphMap)) {
+ console.warn(`"${this.props.name}" is not a valid icon name for family "${fontName}"`);
+ }
+ if (!this.state.fontIsLoaded) {
+ return <Text />;
+ }
+ return (<RNVIconComponent ref={(view) => {
+ this._icon = view;
+ }} {...this.props}/>);
}
- };
+ };
+
+ Icon.Button = createIconButtonComponent(Icon); // Move this line after the class definition
+
+ return Icon;
}
//# sourceMappingURL=createIconSet.js.map
\ No newline at end of file
I tryed to provide a reproduction repo but it does happen with the simple repo I've built ...
The source code of build/createIconSet.js :