react native : custom component with color parameter - reactjs

Im doing the exercises to learn react native on codecademy.
I am told "In React, properties are passed as objects on the first parameter to our components. You need to add this parameter in the custom component and use the color property as the background color."
I need to pass color as a parameter to my Box custom component. This is my code:
export const Box = (color) => (
<View color={color} style={{ width: 100, height: 100, backgroundColor: this.props.color }} />
);
It throws me a syntax error.
I also tried :
export const Box = (color) => (
<View style={{ width: 100, height: 100, backgroundColor: color }} />
);
But I am told "View should have a background color set by the color property.". It's the same when I do
export const Box = (color) => (
<View style={{ width: 100, height: 100, backgroundColor: {color} }} />
);
It's very basic but I'm always mistaken when it comes to calling variables in React and properly using them...
If you could help me that would be great!
thanks

Basically, you can get props like this:
export const Box = ( props ) => (
<View color={props.color} style={{ width: 100, height: 100, backgroundColor: props.color }} />);

Related

How can I use react-native-picker horizontally?

Hi i want to use https://github.com/react-native-picker/picker library horizontally. I also found some picker libraries that can be used horizontally but none of them works as stable as this native picker. I tried to give style transform rotate 90 deg but it caused the view below
And I couldnt reach text style to rotate it -90 deg.
I tried to download library and edit it but it's objective c and I don't know nothing about it. How can I do that any ideas?
My picker code
<Picker style={{
width: 100,
position: 'absolute',
right:50,
}}
itemStyle={{
fontSize: 20,
width: 100,
transform: [{ rotate: '90deg' }],
}}
selectedValue={Value}
onValueChange={(itemValue, itemIndex) => {
setValue(+itemValue);
}}
>
{Values.map(item => (
<Picker.Item
key={item.key}
label={item.value}
value={item.key}
></Picker.Item>
))}
</Picker>
I tried to edit the PickerItem.js in library like below but it didn't work
export default function PickerItem({
color,
label,
testID,
value,
enabled = true,
}: Props): React.Node {
return (
<Option
disabled={enabled === false ? true : undefined}
style={{color}}
testID={testID}
value={value}
label={label}>
<Text style={{transform: '-90deg', backgroundColor: 'red'}}>
{label}
</Text>
</Option>
);
}
and also I tried to add
label.transform = CGaffineTransformMakeRotation(M_PI / 2);
to RNCPicker.m

How to give spacing between the content of view in react native?

I am new in react native,I have to view right and left container given flex-between them,
now I have to give space in contents of left and right container also.
image shown in the below diagram as well as styling code,
const styles = StyleSheet.create({
mainContainer: {
width: "100%",
flexDirection: "row",
height: moderateScale(90),
backgroundColor: "red",
justifyContent: "space-between",
},
containerLeft: {
flexDirection: "row",
top: moderateScale(40),
backgroundColor: "green",
margin: moderateScale(12),
},
containerRightIcons: {
flexDirection: "row",
justifyContent: "flex-end",
top: moderateScale(40),
margin: moderateScale(12),
backgroundColor: "blue",
},
});
Wrap the individual child components inside a View and provide a marginRight when necessary. We could create a new component that handles this behaviour.
export function Spacer({isHorizontal = true, space = 10, children}) {
return <View style={isHorizontal ? {flexDirection: "row"} : null}>
{
React.Children.map(children, (child, index) => {
return index < children.length - 1 ? <View style={{marginRight: space}}>{child}</View> : child
})
}
</View>
}
We use the isHorizontal flag to indicate whether the children are layed out in a row. The default value is set to true to satisfy your current design. However, we can reuse it for column based layouts as well. The default spacing is set to 10. We can control it using the space prop.
Then, use it as follows.
<Spacer>
<Child1 />
<Child2 />
<Child3 />
</Spacer>
We can control the space via props.
<Spacer space={5}>
<Child1 />
<Child2 />
<Child3 />
</Spacer>

How to map over axios array to display image

I want to display an image from my data. It works when I use Flatlist but Flatlist has conflicts with ScrollView, so I had to change my displaying method from Flatlist to mapping with component.
First name renders when I use {profile.first_name}, but the image won't render. I believe the issue is in the source = {} of the Image. I have tried profile.banner_picture and that has not worked either.
const bannerPicture = () => {
return profile.map((profile) => {
return (
<View key={profile.key}
style={{padding: 1}}>
<Image
source={banner_picture}
style = {{
height: 100,
width: 100,
}}/>
<Text>{profile.first_name}</Text>
</View>
);
});
};
When I change
source = {banner_picture}
//to this
source={{uri: banner_picture}}
// it works
const bannerPicture = () => {
return profile.map((profile) => {
return (
<View key={profile.key}
style={{
flex: 1,
height: 400,
width: 400,
padding: 1}}>
<Image
source={{uri: banner_picture}}
style = {{
height: 100,
width: 100,
}}/>
<Text>{profile.first_name}</Text>
</View>
);
});
};

React Native: pointerEvents = 'none' does not work on a stacked FlatList

I have a component that is composed of two child components. The former is the panel with information about the list, and the latter is a FlatList component with the actual contents of the list.
I stacked the components such that the FlatList component is placed on top of the panel component so that when a user scrolls down, the panel is covered by the FlatList, and when the user scrolls up to the beginning of the list, the panel appears again. I also intentionally chose to split the two components rather than incorporating them into a single FlatList to prevent state changes in one component from triggering rerender of the other.
To achieve this, I created a transparent View component in the FlatList component as a header and applied pointerEvents='none' to it so that the panel component behind it is visible and touchable. However, the panel component is not receiving any of the touches.
Here is the simplified code that I wrote:
const List = () => {
/*
*/
return (
<>
<TopPanel props={props} />
<PostArray props={props} />
</>
);
};
const TopPanel = () => {
/*
*/
return (
<View
style={{
width: "100%",
height: 145,
top: 0,
position: "absolute",
zIndex: 1,
}}
>
<PanelComponent />
</View>
);
};
const PostArray = () => {
/*
*/
const ListHeader = () => {
return (
<View
style={{
height: 145,
backgroundColor: "transparent",
width: "100%",
}}
pointerEvents="none"
/>
);
};
return (
<FlatList
style={{ height: "100%", width: "100%", zIndex: 99 }}
data={[0]}
ListHeaderComponent={<ListHeader />}
renderItem={() => <ModalButtons />}
ListFooterComponent={
<View style={{ zIndex: 99, width: "100%" }}>
<FlatList
data={props}
renderItem={renderItem}
windowSize={15}
initialNumToRender={15}
maxToRenderPerBatch={15}
updateCellsBatchingPeriod={100}
keyExtractor={(item, index) => index.toString()}
getItemLayout={(data, index) => ({
length: 120,
offset: 120 * index,
index,
})}
/>
</View>
}
stickyHeaderIndices={[1]}
keyExtractor={(item, index) => index.toString()}
/>
);
};
What is possibly wrong here? Any suggestions/ideas? Thanks!
I'm dealing with a similar issue. It seems that when ListHeaderComponent is rendered, it is being wrapped in a View. You can illustrate this by also setting ListHeaderComponentStyle={{backgroundColor: 'red'}}. While you can change the style of this invisible wrapper View, I don't yet see how to add a property to it like pointerEvents='box-none'.

How to Handle overflowing elements in React-native?

How to use flex in react-native to make any element inside <View></View> to arrange themselves when their length got bigger than their container's ?
Below is my code:
const FilmCasts = ({ artists }) => (
<View style={{ flex: 1, flexDirection: 'row', }}>
{artists.map(artist => (
<Image
key={cast.name}
source={{ uri: artist.img }}
style={{ width: 80, height: 100 }}
/>
))}
</View>
);
This is what I want. I want to make the 5th and others to go below the first row automatically after they hit the screen width limit, like what HTML usually does
But instead, this is what I get when in React Native, the <Image> elements continue to be rendered outside their parent's width
You can use the prop flexWrap:'wrap' for wrapping the elements. flexWrap controls whether children can wrap around after they hit the end of a flex container. More here
const FilmCasts = ({ artists }) => (
<View style={{ flex: 1, flexDirection: 'row',flexWrap:'wrap' }}>
{artists.map(artist => (
<Image
key={cast.name}
source={{ uri: artist.img }}
style={{ width: 80, height: 100 }}
/>
))}
</View>
);
You can simply defined image with dynamically using the Dimension property of react native .
like when you are using
<Image
resizeMode="cover" or try "contain"
key={cast.name}
source={{ uri: artist.img }}
style={{ width: width * 0.5 , height: 100 }} // this will be done currently defining the values .
/>
Here is one blog regarding image handling in react native Click to see the blog
Hope my answer will give an idea to slove your problem

Resources