text string must be rendered within a text component - javascript

I'm getting this error I read some ways to fix it , but nothing worked
<View style={styles.container}>
<StatusBar
backgroundColor="transparent"
translucent
barStyle={theme.dark ? 'light-content' : 'light-content'}
/>
{open ? (
<DateTimePicker
style={{width: '100%', margin: 5}}
mode="date"
value={date}
dateFormat="day month year"
display="calendar"
onChange={handleDate}
/>
) : (
<Button
style={{margin: 5}}
color="#17E5C2"
onPress={() => {
setOpen(true);
}}>
Filtrar por data
</Button>
)}
{Object.values(JSON.parse(route.params.paramKey).message).map(item =>
Object.values(item.createdAt[0]).filter(actualDate =>
actualDate.includes(dateFilter) ? (
<Card mode="outlined" key={uuidv4()}>
<Title>{item?.createdAt[0].value}</Title>
<Button
style={{alignItems: 'flex-start'}}
color="#17E5C2"
icon={
infoVisible
? 'arrow-up-bold-outline'
: 'arrow-down-bold-outline'
}
mode="outlined"
onPress={() => {
handleInfo();
}}>
Ver detalhes
</Button>
{Object.keys(item).map(data => (
<Card.Content
key={uuidv4()}
style={infoVisible ? {display: 'flex'} : {display: 'none'}}
accessible={false}>
<Paragraph style={{fontWeight: 'bold'}}>{data}</Paragraph> // {data} is a string as I checked in console.log
<Paragraph>{item[data][0]?.value}</Paragraph>
</Card.Content>
))}
<Card.Actions>
<Button color={'#17E5C2'}>Edit</Button>
</Card.Actions>
</Card>
) : (
console.log('NO ACTUAL DATA') // When I change console.log to a react child like(<Text>test</Text>) the error appear's instantly
),
),
)}
</View>
The error appear's when I choose a date that has data.
I tried to put console.log besids react child , and when I put it appears to me the data.
So I tought the error could be in my react childs.
I tried to fix my jsx conditional , but not worked , also tried to remove some commas , but also not worked,
and I tried to use <> </> at the top and the end , but also not worked
Complete error message: Error: Text strings must be rendered within a <Text> component.
I tried the entire day so.... it's been dificulty , I want some tips about how to fix it.

One possible problem I can see from your code
Object.values(item.createdAt[0]).filter(actualDate => actualDate.includes(dateFilter) ? <YourComponent> : console.log('NO ACTUAL DATA'))
You're using filter instead of map for a ternary condition.
filter returns true/false value, so you shouldn't use it in this case
If you want to use it, the proper one could be
Object.values(item.createdAt[0]).filter(actualDate => actualDate.includes(dateFilter))

This error comes when you are not wrapping strings within the component or if you are you using some code formatter it sometimes add {" "} outside the components. Check for these scenarios within your components (P.s:- commenting out code component by component might save you some time)

Related

Encountered two children with the same key REACT NATIVE

enter image description here
New in react here. Coding without using div, however is a constant issue the duplicated array and I don't know how to fix it.
return (
<SafeAreaView style={styles.container}>
<Screen>
<FlatList
data={messages}
keyExtractor={(message) => message.id.toString}
renderItem={({item})=>
<ListItem
title={item.title}
subTitle={item.description}
image={item.image}
onPress={()=> console.log("Message selected", item)}
renderRightActions={() => (<ListItemDeleteAction onPress={()=> handleDelete (item)}/>)}
/>}
ItemSeparatorComponent={ListItemSeparator}/>
</Screen>
</SafeAreaView>
First of all the toString is a function not a property so it will be with undefined, so all the items will have key with undefined and this is the cause of the error.
It should be
keyExtractor={(message) => message.id.toString()}
Also, make sure that each message in messages array with unique id.

How can I map over an array, and have a button access the mapped array without being in the map

Project idea: Essentially a stackoverflow clone. I have a "question" (in my case a code error), and you can post potential solutions to that error.
My issue is while mapping over the array of of "solutions", my button is inside the map so it gets duplicated with every solution. How can I move the button outside the map but with it still having access to the mapped information?
This is in React, hooks.
Code:
{props.errors?.map((error, index) => (
<Card
key={index}
title={error.id}
extra={More}
style={{ width: 500 }}
>
<p>{error.errorMessage}</p>
<p>{error.errorType}</p>
{error.solutions.map((solution, index) => {
return (
<>
<SyntaxHighlighter
language={error.errorType.toLowerCase()}
style={rainbow}
>
{solution.solution}
</SyntaxHighlighter>
<Button
type="primary"
onClick={() => {
updateOn();
addSolution(solution);
}}
>
Add Solution
</Button>
</>
);
})}
</Card>
))}

If statement within a map dictionary in react redux

I have a dictionary containing objects with cards. I would only like to display each card if the current user value is equal to the stored user value. IE, if the a given user created that card.
<CardDeck>
{this.props.homeTdps.map(function (tdp, key) {
if ({currentUser.username} == {this.props.tdpDetail.created_by.username})
return (
<Card.Link key={key} href={`/tdps/${tdp.id}/`} style={{ minWidth: '20rem', maxWidth: '20rem' }}>
<Card.Body>
<Card.Title>{tdp.part_name}</Card.Title>
<Card.Text>{tdp.description}</Card.Text>
<Button variant="primary">Download</Button>
</Card.Body>
</Card.Link>
);
// }
})}
</CardDeck>
I am having trouble however syntatically with the the third line:
if ({currentUser.username} == {this.props.tdpDetail.created_by.username})
My current error is as follows...
Any solution is appreciated,
Thanks!
EDIT:
I have also tried removing the curly brackets from the 3rd line:
if (currentUser.username == this.props.tdpDetail.created_by.username)
I then get the error "TypeError: Cannot read property 'props' of undefined".
However, when I print the two values within a header like so, they both print just fine (and the users are the same value).
<h3>{currentUser.username}</h3>
<h3>{this.props.tdpDetail.created_by.username}</h3>
remove the curly bracets from your if statement;
use arrow function at map to properly bind this to your component Class:
{this.props.homeTdps.map((tdp, key) => {
if (currentUser.username == this.props.tdpDetail.created_by.username)
return (
<Card.Link key={key} href={`/tdps/${tdp.id}/`} style={{ minWidth: '20rem', maxWidth: '20rem' }}>
<Card.Body>
<Card.Title>{tdp.part_name}</Card.Title>
<Card.Text>{tdp.description}</Card.Text>
<Button variant="primary">Download</Button>
</Card.Body>
</Card.Link>
);
// }
})}

render FlatList only when data is present

I run a graphql query and depending on the data, render a flatList.
const { data, error } = useGetMyProfileQuery({
//onCompleted: _onCompleted,
onError: _onGetMyProfileQueryError,
});
....
return (
<SafeAreaView style={styles.safeView}>
<Container style={styles.container}>
<View style={styles.listHolder}>
<FlatList
data={data ? data.me.friends : null}
horizontal={false}
renderItem={({ item }) => (
<Friend
friend={item}
onDeleteFriend={onDeleteFriend}
originatorId={data ? data.me.id : null}
/>
)}
keyExtractor={(data: any) => '3'}
ListEmptyComponent={renderEmptyContainer()}
/>
</View>
</Container>
</SafeAreaView>
);
};
However, currently, I have to use ternary operators for checks like data? data.me.friends: null in the FlatList to avoid Typescript errors. If the query fails, and the data is null, It disturbs the whole performance and I will have to use multiple if-else within the whitelist item component too.
So I am looking for the best way such that data is passed into the Flatlist only when the mutation is successful. I could use onCompleted for that but I am not sure how to organize it such that no flat list is displayed from the main return when there's an error.
Also, currently, I am using the same key for all elements of the list but it shouldn't be like that obviously
Render your list when you have data, In this way, you will also have better performance when lesser things are rendered so it will be a conditional rendering of your Flatlist.
{data && data.me && data.me.friends.lenght > 0 &&
<FlatList
data={data.me.friends}
horizontal={false}
renderItem={({ item }) => (
<Friend
friend={item}
onDeleteFriend={onDeleteFriend}
originatorId={data ? data.me.id : null}
/>
)}
keyExtractor={(data: any) => '3'}
ListEmptyComponent={renderEmptyContainer()}
/>
}
Did you tried data={data?.me?.friends}
You can also use this syntax data={data ? data?.me?.friends : []}
You have to used as
<SafeAreaView style={styles.safeView}>
<Container style={styles.container}>
<View style={styles.listHolder}>
<FlatList
data={data?.me?.friends || []}
horizontal={false}
renderItem={({ item }) => (
<Friend
friend={item}
onDeleteFriend={onDeleteFriend}
originatorId={data ? data.me.id : null}
/>
)}
keyExtractor={(data: any) => '3'}
ListEmptyComponent={renderEmptyContainer()}
/>
</View>
</Container>
</SafeAreaView>
data={data?.me?.friends || []} you have to use this that I have already mentioned in the code
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining This link will also useful

React Native FlatList keyboardShouldPersistTaps not persisting

I have a very frustrating situation. Trying to get keyboard to disappear and detect onPress event handler in child row.
Here is what my code looks like:
_renderRow = (prediction) => {
return (
<TouchableOpacity onPress={() => {
Keyboard.dismiss();
this.setState({ location: prediction.description });
}}>
<View style={styles.listItemContainer}>
<Text>{prediction.description}</Text>
</View>
</TouchableOpacity>
)
}
render() {
return (
<View style={styles.wrapper}>
{/* style={[this.state.predictions.length > 0 ? styles.searchContainerSuggest : styles.searchContainer]} */}
<View style={styles.searchContainerSuggest}>
<View style={{paddingLeft: 10, height: 45, display: 'flex', justifyContent: 'center'}}>
<TextInput
placeholder="Enter location"
value={this.state.location}
onChangeText={location => this.onChangeLocation(location)}
style={styles.textInput}
/>
</View>
{this.state.predictions.length && this.state.location !== '' ?
<FlatList
keyboardShouldPersistTaps={'handled'}
refreshing={!this.state.loaded}
initialNumToRender={10}
enableEmptySections={true}
data={this.state.predictions}
keyExtractor={(_, index) => index.toString()}
renderItem={ ({item: prediction}) => this._renderRow(prediction) } />
: null}
</View>
</View>
);
}
I probably need a helping hand or two with regards to how to debug this issue.
Looked up several examples on how to deal with hiding the keyboard and allowing a particular selection to be pressed at the same time.
I thought that keyboardShouldPersistTaps would allow for the child selection to be selected. Upon selection, the onPress event handler will trigger and that will be where I call Keyboard.dismiss() to hide the keyboard. Does not seem to work.
In my case, besides adding keyboardShouldPersistTabs='handled' to the FlatList in question, it was also needed to add keyboardShouldPersistTabs='handled' and nestedScrollEnabled={true} to a parent ScrollView like 2 levels above, wrapping the FlatList I intended to get this behavior with. Check out this issue in react-native repo for more info.
For anyone who is running into the same problem as me. Check whether your FlatList or ScrollView is nested in another FlatList or ScrollView.
If yes, then add
keyboardShouldPersistTaps='handled'
to the element as a props as well.
add keyboardDismissMode="none" to FlatList

Categories

Resources