Warning while using ListItem, FlatList inside ScrollView - scrollview

I get this warning when I tried using Flatlist inside View but same error occurs:
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation - use another VirtualizedList-backed container instead.
The component I am using FlatList inside is:
class About extends Component
{
constructor(props)
{
super(props);
this.state = {
leaders: LEADERS
};
}
render(){
const renderLeaders = ({item,index}) => {
return(
<ListItem
key = {index}
title = {item.name}
subtitle = {item.description}
hideChevron = {true}
leftAvatar = {{ source: require('./images/alberto.png') }}
/>
);
};
return(
<ScrollView>
<History />
<Card title = "Corporate Leadership">
<FlatList
data = {this.state.leaders}
renderItem = {renderLeaders}
keyExtractor = {item => item.id.toString()}
/>
</Card>
</ScrollView>
);
}
}
And can I use leader in place of item here? I tried using it but there was an error.

one way to hack this would be to use react-native-gesture-handler flatlist
it will sort of take over your parenting ScrollView if you absolutely need to have nested scrollers, at least that worked for me when i had this same problem.
As per second part, without delving too deep of what is what, try reading this https://www.barrymichaeldoyle.com/destructuring/#:~:text=Renaming%20Variables%20while%20Destructuring&text=In%20order%20to%20rename%20a,rename%20the%20destructured%20variable%20to or google any other theory on 'destructuring renaming'
if you absolutely need to rename 'item'.

Related

Flatlist inside a function in react native

How can I create an flatlist and add items to it inside a function not a class in react native?? all of the examples online are using classes and I need to use it inside a function !!
I found an example of a FlatList in the React Native docs that is using a functional component:
https://reactnative.dev/docs/flatlist
If you just want the code check out the same example on snack:
https://snack.expo.io/?session_id=snack-session-R6Nsz_Qm1&preview=true&platform=web&iframeId=uetjvvask3&supportedPlatforms=ios,android,web&name=flatlist-simple&description=Example%20usage&waitForData=true
I hope it helped :)
Same as with any other component, there's not much difference between using a FlatList inside a class vs a function. Only the state handling changes a little bit.
The code below will render all items, you'll be able to press on any of them to duplicate the item which should then show up at the bottom of the list.
export const FlatListScreen = props => {
const [items, setItems] = useState([1, 2, 3, 4, 5]);
function duplicateItem(toDuplicate) {
setItems(prev => [...prev, toDuplicate]);
}
return (
<FlatList
data={items}
renderItem={({ item }) => (
<TouchableWithoutFeedback onPress={() => duplicateItem(item)}>
<View>
<Text>
{item}
</Text>
</View>
</TouchableWithoutFeedback>
)}
/>
);
}

React Native - Focus a TextInput (Inside custom Component) that is inside of a Flat List element

I'm a React Native beginner and I'm working with a Flat List and custom Rows. Inside of each custom row, I have elements like Text, TextInput, and Button. The problem is that I need to press one of these buttons that enables and triggers a focus to the TextInput.
I tried implementing that with refs but everything freezes so I don't know how to do that correctly.
My constructor
class EditProfileScreen extends React.Component {
constructor(props) {
super(props);
this._rowRefs = {}
}
My FlatList and MyCustomRow
_renderItem = ({item, index}) => {
return (
<MyCustomRow
fieldname={item.fieldname}
value={item.value}
isEditable={item.isEditable}
editFieldHandler={ this.editFieldHandler }
allowsEdition={item.allowsEdition}
ref={ref => { this._rowRefs[index] = ref}}
/>
)
}
_keyExtractor = (item, index) => index.toString();
render() {
return (
<View style={styles.mainContainer}>
<FlatList
ref={this.flatListRef}
style={styles.flatList}
data={this.state.fields}
renderItem={this._renderItem}
keyExtractor= {this._keyExtractor}
extraData={this.state.refresh}
/>
</View>
);
}
Trying to print the refs:
enableField(name) {
console.log('Printing refs...')
console.log(this._rowRefs) // the Button pressed freezes here
}
I expect to see what's inside of _rowRefs, but instead of that, the button just gets frozen and I never see that result in the console
Try to give the key for each ref (not index)
ref={ref => { this._rowRefs['key1'] = ref}}
and invoke focus action like this:
this._rowRefs['key1'].focus()
Can you try the above code after removing
console.log(this._rowRefs)

React Native TextInput ref always undefined

I have a simple TextInput that I want to put a reference on in my render:
<View>
<TextInput ref={(component) => this._inputElement = component}>Input</TextInput>
{console.log(this._inputElement)}
<Button
onPress={this.addAddress}
title="Submit"
color="#841584"
/>
</View>
I want to then use that ref in a function above that is bound in my contructor:
constructor(props) {
super(props);
this.state = {
addresses: []
};
this.addAddress = this.addAddress.bind(this);
}
addAddress function:
addAddress(event, result) {
console.log("reference:", this._inputElement.value);
}
The console log in both the render and addAddress are always undefined.
I have looked around but no one seems to be having my problem, usually they have a typo or didn't bind the function they then want to call.
Why do I seem unable to have references?
Using State
Usually the way to use TextInput is to store the value in state.
Remember to initialize the address in your state as an empty string, otherwise having a null value for address could cause an error.
constructor(props) {
super(props)
this.state = {
....
address: ''
}
}
Then you could define your text input as follows
<TextInput
onChangeText={address => this.setState({address})}
value={this.state.address}
/>
Then in your addAddress
addAddress(event, result) {
console.log("reference:", this.state.address);
}
Using Refs
Alternatively you could use ._lastNativeText to access it from the reference
<TextInput
ref={ref => { this._inputElement = ref }}>
Input
</TextInput>
then in your addAddress
addAddress(event, result) {
// I always check to make sure that the ref exists
if (this._inputElement) {
console.log("reference:", this._inputElement._lastNativeText);
}
}
I wouldn't recommend the second method as you are accessing private methods that could be liable to change in a future release.
Textinput self-encloses
<View>
<TextInput ref={ref=> (this._inputElement = ref)}/>
<Button
onPress={this.addAddress}
title="Submit"
color="#841584"
/>
</View>
addAddress(event, result) {
console.log("reference:", this._inputElement._lastNativeText); //this get's the value, otherwise it's undefined
}
This snippet works properly in react native and react native web:
const txtRef = useRef(null)
return(
<TextInput
ref={txtRef}
onChangeText={text => txtRef.current.value = text}
/>
<Button
title='log and reset'
onPress={() => {
console.log(txtRef.current.value)
txtRef.current.clear()
txtRef.current.value = ''
}}
/>
)
`

View config not found for name "" react native

when I'm trying to insert Image into View I get this error
View config not found for name ""
renderCategory = (category)=>{
const { Id, Image, Name } = category.item
const { button, image_category, text_category} = style;
return(
<TouchableOpacity style={style.button} onPress={()=>{console.log(Id)}}>
<View style={{flex:1}}>
//here the problem
<Image style={image_category} source={{uri:'https://picsum.photos/150/150'}} /> // when I remove it, it works fine.
<Text>{Name}</Text>
</View>
</TouchableOpacity>
)
}
render() {
const { container } = style;
return (
<View style={container}>
<FlatList style={{margin:5}}
data={this.state.second_categories}
numColumns={3}
keyExtractor={(item, index) => item.id }
renderItem={this.renderCategory}
/>
</View>
)
}
I looked in other post in stackoverflow but nothing solved my issue.
my styles
image_category:{
width: calcSize(width/4),
height: calcSize(width/4)
},
This issue is due to overwriting of the reserved-word Image.
const { Id, Image, Name } = category.item
The Image string being used in the below code is from category.item, and not the one from {Image} from 'react-native'
<Image style={image_category} source={{uri:'https://picsum.photos/150/150'}} />
Therefore you need to replace the Image object in your category.item object to something else, that is not a react-native reserved word to avoid conflicts.
OR
You may make a stateless component for the image and use it
TLDR
Replace the Image object in category.name to something else as it conflicts with react-native's tag Image or make a separate component for the image
I can't tell what you have in image_category but it must have width and height https://facebook.github.io/react-native/docs/image.html

React Native : multiple Navigator navigationBar

I'm stuck with React Native.
I have a "Header" navigationBar, but I want to add another navigationBar to my Navigator component.
render() {
let currentRoute = this.props.route
return (
<Navigator
style={styles.container}
initialRoute={this.props.route}
renderScene={this.router.bind(this)}
navigationBar={<Header />} // << There, how can I simply add another navigationBar ?
/>
);
}
And here's the <Header/> component :
render() {
return <Navigator.NavigationBar
style={styles.navBarContainer}
navState={this.props.navState}
routeMapper={routeMapper}
/>
}
Now, I'm trying to add a <Footer/> component, which would render a similar component as <Header/>, in order to have 2 persistent navigation bar on my app.
How to achieve this ?
I also meet this question, and have resolved it. In React Native, it is not supported to add multiple navigationBar. But, if you want to add another "navigationBar", you can add this "navigationBar" as the sibling node of the Navigator, such as:
render() {
return (
<View style={styles.scene}>
<TopStatusBar
showBackIcon={false}
centerText={LocalizedStrings.appName}
rightIcon={require("../../res/icons/head.png")}
onRightPress={this._onHeadPress.bind(this)}
/>
<Navigator
initialRoute={ROUTE_STACK[0]}
renderScene={this._renderScene.bind(this)}
configureScene={() => Navigator.SceneConfigs.FadeAndroid}
navigationBar={
this.state.displayBottomTabBar ?
<BottomTabBar
ROUTE_STACK={ROUTE_STACK}
/>
:
null
}
onWillFocus={(route) => {
this.presentedRoute = route;
}}
sceneStyle={{flex: 1}}
/>
</View>
);
}
In the upper code, TopStatusBar is a composite component. It persists across scene transitions, just like the navigatorBar.
Good luck!