How to preserve native animation of Switch? - javascript

I'd like to create a basic "setting toggle" component, with Title and Subtitle on the left, and a Switch on the right. I'd like to be able to switch the toggle when the whole component is clicked, not just when the switch is.
In order to achieve this is wrapped the component in a Touchable and execute the supplied onValueChange callback, so the container component can handle the state change of the switch.
export default function SettingToggle({
title,
subtitle,
toggled,
onValueChange,
}) {
return (
<TouchableWithoutFeedback
style={styles.container}
onPress={() => onValueChange(!toggled)}
>
<View>
<Text style={styles.title}>{title}</Text>
<Text style={styles.subtitle}>{subtitle}</Text>
</View>
<Switch
value={toggled}
onValueChange={value => onValueChange(value)}
></Switch>
</TouchableWithoutFeedback>
)
}
Now when I click the Switch, it animates nicely to the other value, but when click the component, the whole component redrawn with the new value of {toggled}, thus on the UI it feels like the switch is instantly changing to the other value.
Question 1: How could I preserve the animation even when the component is clicked, and not just the Switch?
Question 2: From where does React know, that it doesn't need to redraw the view when only the Switch is clicked? The render() method is called, as the parent component's state changes with the onValueChange call, so the SettingToggle is rerendered with a new {toggled} value. I assume the view is "recreated" but under the hood React probably isn't changing the view in the hierarchy with the newly created one, as it somehow knows that it is not needed. How does this work?

Related

React Native get Clicked(pressed) component's attribute

I'm making some dynamic CardView which can show videos like as Facebook.
But there's problem when I press share button and comment button.
Because I need the clicked button's(share, comment) index.
So I think I can use the key prop of button.
I make buttons with touchableOpacity, then I'll set key of touchableOpacity
like this.
<TouchableOpacity
key = {some index}
>
some stuffs
</TouchableOpacity>
Then, I want to get pressed component's attr value( key value at here )
I can find the key value at
ReactNativeComponentTree.getInstanceFromNode(event.nativeEvent)
But this data always show my key is null.
There's no way to get clicked Component's key value?
Thanks for reading.
If you really need the index in the onPress handler, you can create a new inline function and pass along the index instead.
Example
<TouchableOpacity
key={someIndex}
onPress={() => this.handlePress(someIndex)}
>
some stuff
</TouchableOpacity>

Slider component not re-rendered

I made a socket connected app, when a value is changed, all the other clients receive the value modification. This is supposed to lead into an automatic UI change.
Here is my code :
<View style={{marginTop:20}}>
<Slider
ref="container"
minimumValue={0}
maximumValue={100}
value={this.state.briValue}
onValueChange={val => {
this.setState({ briValue: val })
socketEmit('hue-bri', val)
}
}
/>
<Text>Brightness : {this.state.briValue} %</Text>
</View>
The result :
Issue : the slider thumb does not move
I don't know why the Slider component does not re-render while the Text component does.
I tried to force the reload with this.refs.container.forceUpdate() but it does nothing.
I use the Slider from react-native-elements and the Text component is from the original react-native library.
Any help is greatly appreciated.
value prop is only used to initialize the slider.
Ref : https://facebook.github.io/react-native/docs/slider.html#value

React Native: I'm dynamically setting options of one drop down depending on another drop down value selection. But this.setlection

I'm new to react-native so this.setstate method is not predictable for me.
I'm selecting a list of Venue on dropdown 1
according to the venue , the number of available days must be shown as options on the second dropdown.
and similarly according to the second one i have to set timeslots avaiable on the third dropdown
the 2nd to 3rd dropdown works fine for me
but when i select the venue on the first dropdown the 2nd one does not updates. this .setstate is working late there
if i select the venue once more the previously selected days loads not the current one. like setstate method is lagging one step behind
Must be the way i wrote the code ,
I am open to corrections, new structure of coding , anything
but very much in need to get this work
onVenueSelect(index,value){
var props=this.props;
console.log('On venue Select................................')
console.log('index'+index)
console.log('value'+value)
console.log(this.state.venue_id_array[index])
props.getFixtureSlots(this.state.venue_id_array[index], this.state.game_type, this.state.game);
this.setState({selected_venue_id:this.state.venue_id_array[index]})
var days=[];
var timeslots=props.GETFIXTURETIME.timeslot;
for(var i in timeslots){
days.push(timeslots[i].day_of_week);
}
this.setDay_array(days);
this.refs.modal_dayselect.select(-1);
this.setState({selected_venue:value});
}
onDaySelect(index,value){
this.refs.modal_hrsselect.select(-1);
this.props.getFixtureSlots(this.state.selected_venue_id, this.state.game_type, this.state.game);
var props=this.props;
this.setState({selected_day_no:this.state.day_no_array[index]})
console.log(this.state.day_no_array[index])
this.setState({selected_day:value})
}
render_center_selection(){
return(
this.props.selecteddays_array.map((a, i) => {
return( <View key={i} style={{ height:40, borderBottomWidth:2, borderBottomColor: '#ededed' }}>{
<View style={{flexDirection:'column'}}>
<View style={{flexDirection:'row'}}>
<ModalDropdown
style={styles.selection}
defaultValue='Venue'
textStyle={{width:200,fontSize:20,textAlign:'center',color: '#7070D8'}}
dropdownStyle={styles.dropdownstyle}
dropdownTextStyle={{width:350,fontSize:20,textAlign:'center',backgroundColor: '#FDD60B',}}
options={this.state.venue_name_array}
onSelect={(index,value)=>{this.onVenueSelect(index,value)}}/>
<ModalDropdown
ref="modal_dayselect"
style={styles.dayselection}
defaultValue='Day'
textStyle={{width:50,fontSize:15,textAlign:'center',color: '#7070D8'}}
dropdownStyle={styles.daydropdownstyle}
dropdownTextStyle={{width:50,fontSize:15,textAlign:'center',backgroundColor: '#FDD60B',color: '#7070D8'}}
options={this.state.day_array}
onSelect={(index,value)=>{this.onDaySelect(index,value)}}/>
<ModalDropdown
ref="modal_hrsselect"
style={styles.dayselection}
defaultValue='HRS'
textStyle={{width:50,fontSize:15,textAlign:'center',color: '#7070D8'}}
dropdownStyle={styles.daydropdownstyle}
dropdownTextStyle={{width:50,fontSize:15,textAlign:'center',backgroundColor: '#FDD60B',color: '#7070D8'}}
options={this.state.hrs_array}
onSelect={(index,value)=>{this.setState({selected_hr:value})}}/>
</View>
</View>
}</View>);
})
);
}
First thing you have to do is to remove all console.log statements from your code. It really helpful but slows down the app rendering/refreshing rate.
Second thing and the most important thing is to consolidate state setting calls. ie, you only need one setState call inside one action. For every setState call the app re-renders the parts which uses that changed state. So, update multiple states at once otherwise it will not be detected by the react.

Force a mapStateToProps call in React

I'm building a react/redux app and using a ux library called Grommet in the front end. I have the app set up such that I have a series of forms contained within a set of accordions on the page. Here's a whittled downed version containing only one accordion tab:
handleCpuChange(event) {
console.log(event.target)
this.props.updateStore(
{'general': {'cpus': event.target.value} }
)
}
<Accordion>
<AccordionPanel heading="General">
<Box>
<FormFields>
<FormField label='CPUs'>
<NumberInput
value={this.props.form.formData.general.cpus}
onChange={this.handleCpuChange.bind(this)}/>
</FormField>
<FormField label='Ram'>
<NumberInput
defaultValue={this.props.form.formData.general.ram}
onChange={this.handleCpuChange.bind(this)}/>
</FormField>
</FormFields>
</Box>
</AccordionPanel>
</Accordion>
- All of this works fine. The problem is that when I call the handleCpuChange function is called my state/store value gets updated - but my the actual 'value' or 'defaultValue' fields stay the same. For the most part this is no problem but if I close and reopen the accordion the values in those fields resets to the defaults/values supplied through props. I figured that a nice way around this is to remap the state to props whenever the accordion opens or closes that way the actual value updates - but I'm not sure how to do this without reloading the entire page.

Change navigationBar in response to navigation state

I'm writing an application and only want the back button to show when I push new views onto the Navigator (in this case a news article vs. a list of news articles).
It seems like the way to do this would be to modify render() to only include the Back button for certain navigator states. And while the React Native docs suggest components inside the navigator can access it using getContext, this doesn't seem to work for navigatorBar.
Is this the right way to go about it? How would I render the Back button only for certain navigation states?
<Navigator
initialRoute={{name: 'NewsList', index: 0}}
renderScene={this.renderScene}
sceneStyle={styles.navigator}
navigationBar={
<View style={styles.navbar}>
<View style={styles.logo_container}>
<Text style={styles.backButton}>Back</Text>
<Image
source={require( 'image!Logo' )}
style={styles.logo}
/>
</View>
<View style={styles.separator} />
</View>
}
/>
It will help to move your navigationBar code into its own component, pass the route information into it*, then check for route depth.
TLDR;
if (route.index > 0){
//Show Back Button.
}
Or just make your life easier and user either of these plugins to do the job for you.
React-Native-NavBar https://github.com/Kureev/react-native-navbar
React-Native-Router https://github.com/t4t5/react-native-router
*Passing the route may no longer be needed since the addition of Navigator.getContext(this).xxx was added. See navigator documentation for further info on getContext https://facebook.github.io/react-native/docs/navigator.html

Categories