React native chip selection not updating in View - reactjs

`
export default function ChipsTest({ }) {
const interests = [{ name: 'ABC', selected: false, id:1, }, { name: 'XYZ', selected: false, id:2 }, { name: 'Bla bla', selected: false, id: 3 } ];
return ( <View style={styles.container}> {interests.map((interest, index) => ( <TouchableOpacity> <Chip onPress={() => { interest.selected = !interest.selected; interest.name = 'Ali'; console.log(interests);
}}
key={interest.id}
selected={ interest.selected}
> {interest.name} </Chip>
</TouchableOpacity>
))}
</View>
);
`
Hi, I am using react native chips on select I am updating value of selected item but its not reflecting in UI/View. I am able to see value updated in variable/ console. Can anyone help?

I would try to use useState hook to solve your problem.
Basically, React native will re-render your screen's UI if the state changes.
More here: https://felixgerschau.com/react-rerender-components/
Also, I'm not sure what <Chip/> component is. I would move onPress event listener to <TouchableOpacity onPress={...}> OR keep it in <Chip> and remove <TouchableOpacity>.
And then, I would wrap {interest.name} within <Text> {interest.name} </Text>
Good luck!

Related

How to use the same ref between child/parent component

I am trying to control the carousel in the child component from the parent component.
I have used forward ref on the child component but its not working. Where am I going wrong?
Parent:
const CoachingCarousel = ({}) => {
const carouselRef = useRef<Lottie>(null);
const renderItem = ({item}: any) => {
return (
<View style={styles.renderItemContainer}>
{item.icon}
<Text style={[styles.titletext, spacing.gbMt7]} variant="titleLarge">
{item.title}
</Text>
<Text style={[styles.subtitleText, spacing.gbMt4]} variant="bodyMedium">
{item.text}
</Text>
<Text
style={[styles.next]}
variant="bodyLarge"
onPress={() =>
carouselRef?.current?.goToSlide(
totalSlides !== item.key
? item.key
: () => {
setCoachingScreenCompleted('CoachingScreenCompleted', true),
console.log('Go to homepage');
},
)
}>
{totalSlides !== item.key ? 'Next tbc' : 'Done tbc'}
</Text>
</View>
);
};
return (
<AppCarousel slides={slides} renderItem={renderItem} ref={carouselRef} />
);
};
Child:
const AppCarousel = React.forwardRef(
({style, slides, renderItem}: props, ref) => {
return (
<View style={[styles.container, style]}>
<AppIntroSlider
ref={ref}
renderItem={renderItem}
data={slides}
/>
</View>
);
},
);
Here a is React rule,
1. Do not declare components within other components, this will lead to very weird behaviors in React.
2. Also you cannot share ref between two components at the same time whether they are parent/child or siblings.
Answer
Also from what I am seeing, you are using a ref to keep track of the current slide. ref does not rerender in React so you will not see your changes. Try using useState.
useRef is for non rerendering values or to keep track of DOM nodes which is not necessary in your case.
I found this tutorial to be quite well. One critic would be the over complicated use of React.children.map and React.children.clone although they have their use cases.

How to put value from an object inside an array into a flatlist React Native

so I have this array:
let Reviews = [
{
name: "Tibo Mertens",
review: "Very nice model",
},
{
name: "Quintt Adam",
review: "I like the car",
},
];
And a Flatlist:
<View>
<FlatList
data={Reviews}
renderItem={({ item }) => {
<View>
<Text>{item.name}</Text>
</View>;
}}
></FlatList>
</View>
Where you see {item.name} I want to display the names of the objects in the flatlist. But nothing is showing, the value is undefined. How do I get the right values?
There are a few things wrong with your code.
You are not returning the View in renderItem.
You having a semi-colon on the end of the View in renderItem - You should remove that.
FlatList should be self-closing.
<View>
<FlatList
data={Reviews}
renderItem={({ item }) =>
<View><Text>{item.name}</Text></View>
}
/>
</View>
To note, the above is an implicit return and is an alternative to the following:
renderItem={({ item }) => {
return <View><Text>{item.name}</Text></View>
}}

Run CSSTransition inside TransitionGroup when any value changes

I'm looking at the TransitionGroup documentation example, and I'm trying to update it to run the CSSTransition whenever the text value is updated for an existing item.
I have set up a codesandbox to show my current attempt.
const [items, setItems] = useState([
{ id: 1, text: 'Hello world!' },
{ id: 2, text: 'How are you?' },
]);
return (
<Container style={{ marginTop: '2rem' }}>
<ListGroup style={{ marginBottom: '1rem' }}>
<TransitionGroup className="todo-list">
{items.map(({ id, text }) => (
<CSSTransition
key={id}
timeout={500}
classNames="item">
<ListGroup.Item>{text}</ListGroup.Item>
</CSSTransition>
))}
</TransitionGroup>
</ListGroup>
<Button
onClick={() => {
setItems((items) => [
{ id: 1, text: 'Hello to you!' },
{ id: 2, text: 'How do you do?' },
]);
}}>
Update Items
</Button>
</Container>
);
When I click the button, the text content updates without the CSSTransition. I know this is because of the id not changing, and this is what key is set to, but how do I have TransitionGroup take into account the text value?
How do I keep the same id but update the text value with a transition?
Since key={id}, the key won't change when the text is updated, and the CSSTransition won't trigger because it doesn't get rerendered.
We can change the key to include the id and the text, so the component will always get rerendered when the text changes. We also want to add exit={false} to prevent us from seeing extra components while the new components are transitioning in. Here's what that should look like:
<CSSTransition
key={`${id}${text}`}
timeout={500}
classNames="item"
exit={false}
>
Here's a codesandbox example of this solution.

fetch multiple image source before render react native

I would like show image on my markers, but it works only when I use the icon attribute of the marker. I need to use the subview to manage the style. When I use the ICON attribute, the view image appear (so I have two image on the map) but not showing when it's in comment.
This how I fetch the data and update the state.
componentDidMount(){
getmarkers().then(data => {
let test = []
data.forEach(element => {
test.push(
{
latlng:
{
latitude: JSON.parse(element.latitude),
longitude: JSON.parse(element.longitude)
},
name: JSON.parse(element.images)[0],
id: element.id,
image: JSON.parse(element.images)[0]
}
)
});
this.setState({ markers: test, loaded: true })
})
}
}
This is my view
{this.state.markers.map((marker, i) => (
<Marker
key={i}
coordinate={marker.latlng}
title={marker.name}
description={marker.name}
tracksViewChanges={false}
// icon={{ uri: 'https://www.testeed.com/uploads/minifiedplaces/' + marker.image}}
>
<View>
<Image source={{ uri: 'https://www.testeed.com/uploads/minifiedplaces/' + marker.image }} style={{ width: 40, height: 40, borderRadius: 6 }} />
</View>
</Marker>
))}
The issue come from Trackviewchange. If you put this value to false. the application is lagging. then if you put the value to false, the application do not load the image at first loading.
So you have to init Trackviewchange to True and create promise after the execution of your fetch/foreach, if it doesn't work, you can do a a setimeout or setinterval to change the value of trackviewchange to false to show images changes and get a better smooth user experience.
const customMarkerImage = require("../../../customMarkerImage.png");
<MapView.Marker>
<View >
<Image source={customMarkerImage} onLoad={() => this.forceUpdate()}>
</Image>
</View>
</MapView.Marker>
It is probably about this issue : https://github.com/react-native-community/react-native-maps/issues/924

dynamically displaying scrolling list of characters via FlatList

I have an array in a file called arrays.js like this:
export var Characters = [
{
id: 1,
Name: "Dirk Longsword"
Avatar: require('./images/profile1.png')
},
{
id: 2,
Name: "Msal Reaper"
Avatar: require('./images/profile2.png')
},
{
id: 3,
Name: "Stone Rockthrow"
Avatar: require('./images/profile3.png')
}
]
On my main screen, I'm trying to write it all out dynamically via a scrollable like this:
import {Characters} from './arrays';
render() {
return (
<FlatList
data={Characters}
keyExtractor={
character => character.Name
}
renderItem={
({character}) => (
<View style={[styles.flexRow]}>
<Text>
{character.Name}
</Text>
<Image style={[ styles.charImage ]}
source={character.Avatar}
/>
</View>
)
}
/>
}
But I keep getting this error:
'undefined' is not an object(character.Name)
I'm not sure what I'm doing wrong and could use a helping hand.
Thanks!
First, I'll be ignoring the many syntax errors in the code you posted.
Second, you are misunderstanding how { } destructuring works in Javascript. You are attempting to destructure character from the data passed to Flatlist's renderItem. There is no such key value for the object passed to renderItem. If you look at the docs, you'll see there there are only the following keys:
item <- This contains the "character" object that you are trying to access.
index
separators
You can fix your code in two ways. One of which is to not destructure at all:
renderItem={
(character) => (
<View style={[styles.flexRow]}>
<Text>
{character.item.Name}
</Text>
<Image style={[ styles.charImage ]}
source={character.item.Avatar}
/>
</View>
)
}
The other is to destructure item and use that in the manner you're trying to do with character:
renderItem={
({item}) => (
<View style={[styles.flexRow]}>
<Text>
{item.Name}
</Text>
<Image style={[ styles.charImage ]}
source={item.Avatar}
/>
</View>
)
}

Resources