React native conditional spread prop - javascript

I am trying to spread props if testId exists. Can anyone please help?
I have tried these but allgenerate a compile error:
<Text style={forms.iosLink}
..{testId && TestIdHelper(testId)}>
<Text style={forms.iosLink}
{...(TestIdHelper(testId) && testId)}>
and
<Text style={forms.iosLink}
{testId ? { ...(TestIdHelper(testId)} : ''}>
I get the error, Unexpected token, expected "..."
Any ideas?

when you spread entity, it need to be an object.
<Text style={forms.iosLink}
{...(TestIdHelper(testId) ? { testId }) : {}}>

Related

How to solve: Objects are not valid as a React child (found: object with keys {_U, _V, _W, _X}?

Im trying to map my state , but it allways returns me this error, someone knows how to solve it ?
useEffect(() => {
if (mounted && userForm.length > 0) {
console.log(userForm, 'campos:', userForm.fields);
return;
} else {
setuserForm(JSON.parse(route.params.paramKey));
console.log(userForm);
}
}, [userForm]);
return (
<SafeAreaView style={{flex: 1}}>
<View style={styles.container}>
<Text style={styles.textStyle}>COLLECTION :</Text>
{userForm.length > 0 ? (
userForm.map((item) => (
<Text key={uuid.v4()}>{item.fields}</Text>
))
) : (
<Text key={uuid.v4()}> Loading ...</Text>
)}
</View>
</SafeAreaView>
);
};
what I'm trying to do is render all my fields and then handle the following types.
If I understand you correctly, you are trying to render item.field as node. However, seems that this is an array, so you need to map it one more time.
For example, if it contains strings it might looks like this:
<Text key={uuid.v4()}>{item.fields?.concat('')}</Text>
In case filds contains objects you have to map it to the new component, like this:
<Text key={uuid.v4()}>{item.fields?.map((field, i)=> <div key={i}>{field.someProp}</div>}</Text>
In case you don't know what is inside the fields, check the Network tab in the ChromeDeveloperTools (F12) or use JSON.stringify

Error: Cannot read property 'navigate' of undefined

enter image description hereWhen using navigation v5, I encounter an error can not read property navigate of undefined
const Categories=({navigation})=> {
return (
<View >
<Text style={Styles.TextCategories}>دسته بندی ها</Text>
{/* ---------------------------------------------------------------لایه کلی صفحه---------------------------------- */}
<View style={Styles.View}>
{/* --------------------------------------------------------------- لایه دکمه ها---------------------------------- */}
<Button style={Styles.Button} onPress={()=>navigation.navigate('Homesales')}>
<MaterialIcons name="waves" size={30} color={"#0c7656"} />
<Text style={Styles.Text}>زمین</Text>
</Button>
const Home=()=>{
useEffect(()=>{
axios.get('https://jsonplaceholder.typicode.com/posts').then((response)=>console.log(response.data)).catch((e)=>console.log(e))
},[])
return (
<Categories/>
);
}
export default React.memo(Home);
why don't you use navigation hook of react-navigation-v5?? instead of passing navigation as prop try to "useNavigation()" hook, this way you will have access to a valid navigation object from anywhere
const navigation=useNavigation()
for using navigation
navigation.navigate('')
You are passing a object that does not has property 'navigation' to component Categories
You need to check at the parent component, seem that props/navigation is null here.

Unable to use the item value from FlatLists renderItem in react native

I am pretty new to coding so really struggling with this but I'm sure it's something simple.
When using Flatlist renderItem item
_renderItem = ( item ) => {
return (<View style={{ flex: 1 }}>
<Text>{item}</Text>
<Text>{GLOBAL.products[item].title}</Text>
</View >)
};
render() {
return (
<View style={styles.list}>
<FlatList
data={[9,10]}
renderItem={ this._renderItem} />
</View>
)
}
The <Text>{item}</Text> works fine and first renders 9 and then renders 10.
But the <Text>{GLOBAL.products[item].title}</Text> is giving me the error:
TypeError: TypeError: undefined is not an object (evaluating '_global.default.products[item].title
The <Text>{GLOBAL.products[**{**item**}**].title}</Text> doesn't work. and also the _renderItem = ( **{**item**}** ) => {.
The <Text>{GLOBAL.products[9].title}</Text> works fine. also have tried GLOBAL.products[parseInt(item)].title
It is obvious you don't know about JavaScript Object and child calling. when you call a child but its parent does not exist, you definitely got an error also in the Text component of React Native you should pass at least an empty string.
You should develop the chaining calling of children defensively. for this, I offer you to read about optional chaining and add it to your project by using this link.
After installing you can write the _renderItem function like below:
_renderItem = item => (
<View style={{ flex: 1 }}>
<Text>{item}</Text>
<Text>{GLOBAL?.products[item]?.title || ''}</Text>
</View >
);
Or there is a better way to use lodash.get by installing it with yarn add lodash.get or npm install --save lodash.get, and then use it like below:
import get from 'lodash.get';
~~~
_renderItem = item => (
<View style={{ flex: 1 }}>
<Text>{item}</Text>
<Text>{get(GLOBAL, ['products', 'item', 'title'], '')}</Text>
</View >
);
I prefer the second one. this defensive programming prevents your app from crashing.

React Native Prevent Undefined Objects

I am grabbing data from an API to display an image based on the API value. The following code works perfect IF there is an image in the object. If an API item does not have an image the app throws an "Undefined is not an object" error.
<View>
<Image source={{uri:props.enclosures[0].url}} style={styles.mainPhoto} />
</View>
I have tried the following code to check if the value exists first, but it still throws exact same error if an API item does not have image.
<View>
{props.enclosures[0].url ?
<Image source={{uri:props.enclosures[0].url}} style={styles.mainPhoto} />
:
<Text>No Image</Text>
}
</View>
If you are going to access multiple properties of a nested object, you should check everything, like so
<View> // Checking everthing so it never throws an error
{props.enclosures && props.enclosures[0] && props.enclosures[0].url ?
<Image source={{uri:props.enclosures[0].url}} style={styles.mainPhoto} />
:
<Text>No Image</Text>
}
</View>
To prevent undefined error you can also use path from Ramda library. It allows you to safely access any nested object/array.
const MyComponent = (props) => {
const apiImage = path(["enclosures", 0, "url"], props);
return {
<View>
{apiImage ?
<Image source={{uri:apiImage}} style={styles.mainPhoto} />
:
<Text>No Image</Text>
}
</View>
}
}

React native: "Invariant Violation: Objects are not valid as a React child"

Have googled the entire day and found similar problems but no answers that fixes my problem. It seems as though the "timeLeft" put as the "until" under countdown is an object, even though the log (typeof timeLeft) says that it's a number (as it's supposed to be).
I get errormessage:
Invariant Violation: Invariant Violation: Invariant Violation: Objects are not valid as a React child (found: object with keys {_40, _65, _55, _72}). If you meant to render a collection of children, use an array instead.
render() {
return (
<View style={styles.container}>
<ScrollView>
<View>
{
this.state.auctions.map(async (auctionObject, index) => {
var timeLeft = await this.getTimeLeft(auctionObject.expiration);
console.log(JSON.stringify(timeLeft) + typeof timeLeft)
return <View style={styles.auctionObject} key={index + 'a'}>
<Text key={index + 'b'} onPress={() => this._renderObjectPage(auctionObject)}>
TITLE: {auctionObject.title} {"\n"}
HIGHEST BID: {auctionObject.highestBid} {"\n"}
NUMBER OF LIKES:{auctionObject.numberOfLikes}
</Text>
<CountDown key={index + 'c'}
until={timeLeft}
timetoShow={('H', 'M', 'S')}
size={12}
/>
</View>
}
)
}
</View>
</ScrollView>
Thank you
The problem is that your render function is outputting a list of Promise objects (which isn't valid react code):
this.state.auctions.map(async (auctionObject, index) => {
var timeLeft = await this.getTimeLeft(auctionObject.expiration);
Question: Are you sure that the getTimeLeft operation needs to be async? If so then this operation will need to be done outside of the render function (possibly in componentDidMount or componentDidUpdate).
If you can change getTimeLeft to be synchronous, it will work:
this.state.auctions.map((auctionObject, index) => {
var timeLeft = this.getTimeLeft(auctionObject.expiration);

Categories