TouchableHighLight onPress inside a map function in react native - scope

I have an array of images that I want to display in a component in react native.
I use map function to iterate over the array and display it. I also have a delete button on top of the image.
The relevant code is :
this.state.imgs.map(function(img,i){
return (
<View style={{alignItems:'center',justifyContent:'center', height:75, width:75, borderRadius:25}}>
<Image style={{position:'absolute',resizeMode:'cover', top:0,left:0, borderRadius:38,height:75, width:75, opacity:0.5}} source={{uri: img.path }} />
<TouchableHighlight onPress={() => this.removeItem(i)}>
<Image style={{}} source={require('./Images/images_asset65.png')} />
</TouchableHighlight>
</View>
);
})
The problem is the TouchableHighlight, where I have an event, when the event fires I get an error regarding "this" (undefined is not a function).
I know this is a scope problem but I cant figure it out.
Is the use of an arrow function is correct here?

If you want to use this inside your map function, you have to change to an arrow function so this points to the outer scope.
this.state.imgs.map((img, i) => {
return (
<View style={{alignItems:'center',justifyContent:'center', height:75, width:75, borderRadius:25}}>
<Image style={{position:'absolute',resizeMode:'cover', top:0,left:0, borderRadius:38,height:75, width:75, opacity:0.5}} source={{uri: img.path }} />
<TouchableHighlight onPress={() => this.removeItem(i)}>
<Image style={{}} source={require('./Images/images_asset65.png')} />
</TouchableHighlight>
</View>
);
})

When you use function keyword in your code, then you lose the context and function creates its own. If you use function it is better not to forget binding these functions with bind(this) so that these functions share the same context. So in your relevant code you should change your last line to }.bind(this)). It is better to remember using bind(this) somehow when using the function keyword, even the better option is not using function and stick with the goodies comes with ES6. Last but not least one should always read docs.

Related

How do I avoid visual bug when navigating from one screen to another? - React Native Expo

I'm creating a sign in screen and a create account screen on my application. I have buttons that go back and forth to each other. Both screens work fine individually. When I do this, there can often be a visual error like so:
My App.js Code:
const App = () => {
return (
<NavigationContainer theme={theme}>
<Stack.Navigator screenOptions={{ headerShown: false}} initialRouteName="CreateAccountScreen">
<Stack.Screen name ="CreateAccountScreen" component={CreateAccountScreen} />
<Stack.Screen name ="SignInScreen" component={ SignInScreen } />
</Stack.Navigator>
</NavigationContainer>
);
}
Code from each Screens button that goes back and forth:
onSignUpButtonPressed = () => {
navigation.navigate("SignInScreen")
}
onCreateAccountButtonPressed = () => {
navigation.navigate("CreateAccountScreen")
}
Displays seem to overlay themselves in a bad way
I've tried a bunch of things and this has happened on several screens...
Your initialRouteName is set up as we can see but on your Stack.Screen you also give it the Component attribute.
I did a test based on how my navigation looks and I did not get the visual bug you showed so I think if you removed the component attribute and maybe just put the component tag inside your Stack.Screen as shown below it might work. Just imagine my Home is your CreateAccountScreen.
<Stack.Navigator
initialRouteName='Home'
>
<Stack.Screen
name="Home"
options={{
headerShown: false,
}}
>
{props => <Home {...props} username='Bella' />}
</Stack.Screen>
You also dont have the code in your question to define Stack like this:
const Stack = createStackNavigator();

Render a <Text> as <p> with fluent ui react

I would like to be able to render the ms fluent-ui as a paragraph instead of the default span for accessibility reasons but the documentation is very unclear on what exact input is expected and in what format. I would expect something like this:
<Text as={<p />}>
test
</Text>
or:
<Text as={(someProps) => <p>{someProps}</p>}>
test
</Text>
Can anyone help me out with how this is supposed to be done?
You are on the right path with second example. The problem is you need React Component instead to return directly <p> tag.
// Custom Paragraph Component
const Paragraph = ({ children }) => <p>{children}</p>
<Text as={Paragraph}>Test</Text>
Codepen working example.

React Native no luck with fixing my FlatList - VirtualizedList: You have a large list that is slow to update

I have been trying to fix my virtualize list issue du to too many rendering apparently...
this is happening when I go back and forth, from one item here: restaurant (restaurant screen) to the flatList with the tab bar, I have also been trying to render less items, but even when the limit is down it doesn't seems to work...
What I use
I'm using a animated bottom sheet that display the flatList on top of the mapView
what I tried
I have been looking ,and tried that out
and also that
and those issues too
I have tried to use the Hook useMemo but apparently it does work for complex stuff such as arrays, or I my config of the dependency was wrong:
const renderMemo = useMemo(() => renderItem, []) //what should be in the array? data? !isLoading ? limit ? ( the limit is change when onEndReached)
(code below)
I have tried to make a pure component of my list (renderItem)
ISSUE
I still get :
VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc. Object {
"contentLength": 5148.66650390625,
"dt": 4164,
"prevDt": 2313,
}
and in this particular set up after not doing anything for a while I got that error:
_Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
at [native code]:null in dispatchAction
at containers/HomeScreen.js:87:16 in fetchData
at [native code]:null in flushedQueue
at [native code]:null in invokeCallbackAndReturnFlushedQueue_
I haven't tried shouldComponentUpdate as I don't really understand it... I mean I don't know where to locate it...
where should I head now ? memo maybe?
is there a way maybe to get less render from useEffect
CODE
repo native
HomeScreen:
const renderContent = () =>
!isLoading ? (
<View style={styles.firstParentViewRenderContent}>
....
<FlatListContents
data={data}
navigation={navigation}
setLimit={setLimit}
limit={limit}
skip={skip}
setSkip={setSkip}
handleColors={handleColors}
/>
</View>
flatListContents component:
const handleLoadMore = () => {
console.trace("handleMore");
// console.log(limit);
setIsLoadingMore(true);
// if (limit > 30) setIsLoadingMore(false);
if (!isLoading) {
setLimit(limit + 10);
setIsLoadingMore(false);
}
};
// const renderMemo = useMemo(() => renderItem, []);
const renderItem = ({ item }) => {
return (
<PureCompFlatlist
item={item}
handleColors={handleColors}
navigation={navigation}
/>
);
};
return (
<FlatList
data={data}
keyExtractor={(item) => String(item.placeId)}
renderItem={renderItem}
removeClippedSubviews={true}
maxToRenderPerBatch={20}
initialNumToRender={5}
windowSize={limit}
getItemLayout={(data, index) => {
return {
length: styles.flatList.height,
offset: 25 * styles.flatList.height,
index,
};
}}
onEndReached={handleLoadMore}
onEndReachedThreshold={0.5}
// ListFooterComponent={renderFooter}
/>
PureCompFlat:
export class PureCompFlatlist extends PureComponent {
render() {
const { item, handleColors, navigation } = this.props;
return (
<TouchableOpacity
style={styles.flatList}
onPress={() =>
navigation.navigate("Restaurant", {
id: item.placeId,
name: item.name,
description: item.description,
rating: item.rating,
thumbnail: item.thumbnail,
color: handleColors(item.type),
})
}
>
<Image style={styles.flatListPic} source={{ uri: item.thumbnail }} />
<View style={styles.flatListContent}>
<View style={styles.flatListNameType}>
<Text style={styles.flatListText}>{item.name}</Text>
<Text style={styles.flatListText}>{item.type}</Text>
</View>
<Text style={styles.flatListText}>{item.rating}</Text>
<Text style={styles.flatListText} numberOfLines={2}>
{item.description}
</Text>
</View>
</TouchableOpacity>
);
}
}
thanks in advance

How to change the values in MultiSlider in react-native?

I am working on react-native <MultiSlider> component, but one thing i just want to know, how do i change the value when i am sliding.
Default Value:
Sliding Values:
Code:
constructor() {
super();
this.state = {
priceRange : [0,10],
};
}
sliderOnChangeValue(values){
return(
<Text style={Styles.filter_label_label}>0 - 35,000</Text>
);
}
<View>
<View>
<Text>PRICING</Text>
</View>
<View>
{this.sliderOnChangeValue()}
</View>
</View>
<MultiSlider
values={this.state.priceRange}
sliderLength={300}
onValuesChange={this.sliderOnChangeValue} />
So on the above code i am calling sliderOnChangeValue() function onValuesChange i want to change the <Text> component values on range change.
Please kindly go through my above post and let me know if you find any solution.
Thanks
I recommend you refamiliarize yourself with the basics of React. Your approach is rather fundamentally flawed.
Callback functions cannot render things, they must update your component's state and your render function should output the UI based on state and props.
Follow the React Native Slider example on the docs website. It's nearly exactly what you want.
Try below code:
values={[parseInt(this.state.multiSliderValue[0]), parseInt(this.state.multiSliderValue[1])]}
and notice above code
<MultiSlider
values={[parseInt(this.state.multiSliderValue[0]), parseInt(this.state.multiSliderValue[1])]}
sliderLength={290}
onValuesChangeFinish={this.multiSliderValuesChange}
selectedStyle={{backgroundColor: '#f5a540'}}
min={16}
markerStyle={{backgroundColor: '#f5a540'}}
max={99}
step={1}
snapped
/>
Its working with me.

Alloy require could not find module

Problem: Trying out a simple demo for a custom tabgroup in Titanium Alloy. However, the compiler keeps failing with the message Could not find module: common. What I thought would be a straightforward test is anything but.
Titanium SDK: 3.1.3.GA
OS: iOS 7.x
controllers/index.js
var common = require('common');
function tabGroupClicked(e) {
common.tabGroupClicked(e);
}
Alloy.Globals.parent = $;
Alloy.Globals.tabGroup = $.tabGroup;
Alloy.Globals.selectedTab = $.tab1;
$.index.open();
controllers/common.js
exports.tabGroupClicked = function(e){
if (Alloy.Globals.selectedTab !== e.source){
// reset the selected tab
Alloy.Globals.previousTab = Alloy.Globals.selectedTab;
Alloy.Globals.selectedTab = e.source;
// change the selected flag
Alloy.Globals.previousTab.selected = false;
Alloy.Globals.selectedTab.selected = true;
// change the background image
Alloy.Globals.previousTab.backgroundImage = Alloy.Globals.previousTab.disabledImage;
Alloy.Globals.selectedTab.backgroundImage = Alloy.Globals.selectedTab.selectedImage;
// swapping the zindexes of the childTabs
Alloy.Globals.parent.getView(Alloy.Globals.previousTab.childTab).getView().zIndex=2;
Alloy.Globals.parent.getView(Alloy.Globals.selectedTab.childTab).getView().zIndex=3;
}
};
index.xml
<Alloy>
<Window id="index" class="container">
<View id="tabGroupWindow" zIndex="0" class="container">
<Require src="tabThreeView" id="tabThreeView"/>
<Require src="tabTwoView" id="tabTwoView"/>
<Require src="tabOneView" id="tabOneView" />
</View>
<!-- Custom tab group -->
<View id="tabGroup">
<View id="tab1" onClick="tabGroupClicked"></View>
<View id="tab2" onClick="tabGroupClicked"></View>
<View id="tab3" onClick="tabGroupClicked"></View>
</View>
</Window>
</Alloy>
Can anyone see anything that I'm obviously overlooking? I've cleaned the project, restarted Studio, scoured forums for any reference to this issue. Not finding a reference usually means I forgot some basic detail.
Your help is appreciated.
To use the require function, you have to create a service.
So the common.js module as you nammed it, has to be under this folder : app/lib. If it's not in the lib folder, it will not be recognized, and it will not be required.
You can find more help in this page.

Resources