Close v-navigation-drawer from parent component when clicking outside - vue.js

I have a navigation drawer that is its own component. The toggling of visibility is controlled from the parent component by passing a prop that is assigned as the v-model of the v-navigation-drawer. I then emit an event form child to update the prop from the parent. That works fine. However, when clicking from outside, the navigation drawer doesn't close. I came up with the solution below to manually close the navigation drawer on outside click. I added a condition so that it only responds when the target is the overlay. Is there a better way of handling this so that the navigation-drawer closes when clicking only on the overlay and not on other elements from the parent?
//DrawerComponent.vue
<v-navigation-drawer
v-model="isDrawerShowing"
temporary
fixed
:width=width
:height="height"
right
stateless
v-click-outside="hideDrawer"
></v-navigation-drawer>
hideDrawer(e) {
if(e.target.className === "v-overlay__scrim") {
this.$emit('hide-drawer',false);
}
}

Related

How to get value from header component? React Navigation

I have a button on my header right that open up a drop down component. The component allow user to make some selection and apply it after the user hit the 'apply' button.
After the apply button pressed, it should be able to pass the value back to the 'main screen' component. How do I pass the value back to the 'main screen' ?
This is my interface , if you're wondering what I'm trying to do.
edit
I tried to pass in the useState function to the header component to update the state after the apply button pressed by passing it using the setParam from react navigation props. Is there any other better way to get the value ??
You can do it simply like:
props.navigation('Home', { state: SOME_VALUE });
Here is the react navigation doc to do this.
React navigation passing params to previous screen
Or you can use redux store.

Nested component state control

I have an overlay/modal within a screen that resides under a parent container that I would like to control as follows:
On load, visibility is false
When user performs and act on the screen/container component, the overlay shows.
The user can close the overlay by clicking on the area outside the overlay (onBackdropPress)
Data within the overlay is provided by the parent container (through state).
Should I generate a state within the screen component and assign props to it?
class Screen extends Component {
state = { visible: this.props.visible, data: this.props.data }
render () {
return (<Overlay isVisible={this.state.visible} onBackdropPress={this.setState({visible: false})}><Text>{data}</Text></Overlay>)
}
}
How do I deal with the problem that by setting the state within the Screen component, the parent container's state is not updated yet?
Visibility is still set to true in the parent container even though it's already set to false in the screen component.
<Screen visible={this.state.visible} data={this.state.data}>

How to call a method from different component in React Native

I have a snack setup:
https://snack.expo.io/#sj458147/view-not-scrolling
when you click show modal -> Click next button the View horizontally scrolls (animated), which then displays an image carousel. Now when you click an image, the View should horizontally scroll again but I get the error undefined is not an object. The error lies within the file:
SliderEntry.js
select = () => {
this.MyScrollView.current.moveToPage(3);
};
any help resolving the issue would be appreciated. Thanks in advance
You have MyScrollView ref in ShowModal. There are 2 ways:
Not recommend: Pass MyScrollView ref as props to Slider, then pass to SliderEntry
Recommend: create a callback as props in SliderEntry. Callback to Slider, then callback to ShowModal
Pass your function in props to other components and then access these functions from your another component.
You can find the answer here
React : Pass function to child component

react native component inside component

I have component that includes a textInput and another component with a slider that also has a textInput. Since both textInputs are exactly the same I am importing the component with the textInput into the component with the slider. When I focus on the textInput I want to make the slider disappear (focus: true -> hide slider , focus: false -> show slider)
Since the textInput is on a child component I'm using a callback to get the focus state of the child and based on this update the focus state on the parent.
The issue is that since I'm updating the state of the parent the whole thing gets rerendered and this also rerenders the child which returns the state again which makes the parent rerender again and makes the child rerender again which makes the child return the state and rerender the parent again and so on.
I did a console.log on both components and it seems this happens around 5 times until it stops. Sometimes with the slider showing even though focus is true other times the slider is hidden.
My question will be how do I make this run only once or at least how do I make the slider always hidden when focus = true (I have merge everything in one component and that solves the issue but I have another view that only needs the textInput so it will be great if I can split this in two components)
I think you're trying to change the state of the parent component using a lifecycle method like componentDidUpdate and that causes the rendering loop. Instead, use a function as a prop to set the new state, then use shouldComponentUpdate method like this:
In the child component:
func(param) {
this.props.setParam(param)
}
And in the parent component:
setParam(param) {
this.setState(
// set the param here
);
}
shouldComponentUpdate(nextProps, nextState) {
// do something with nextState
}
render() {
// do something
return <Child setParam={this.setParam} ... >;
}
That should work.

TouchableHighlight and TouchableOpacity get highlighted on render()

I experience a behaviour where TouchableHighlight and TouchableOpacity reacts visually upon render (onPress is not being called).
One thing is that it looks just a little strange, when I enter the page and my button make a small "blink". This is strange but tolerable. The more frustrating part is that if I alter state for the parent component and thus invoke a re-render(), the button will "blink" again, making all buttons blink whenever I alter state.
Pushing the buttons alters page state, and thus pushing a button makes both buttons "blink".
I use react-redux, but this should not affect this behaviour.
The code below is just for illustration.
render()
{
return(
<View>
<ToucableHightlight> //Click here changes state
<Content/>
</ToucableHightlight>
<ToucableHightlight> //Click here changes state
<Content/>
</ToucableHightlight>
<View>
);
}
Add activeOpacity in TouchableOpacity and it will force to not blink.
<TouchableOpacity style={styles.opecity} activeOpacity={1}>
I solved the problem. Earlier during my render function i defined the "Content"-components, resulting in new (but alike) components being defined during each update. Placing the definitions of "Content" outside of the render function fixed it, so that the components no longer flashes when the page is re-rendered.
This explains why my component was rendered as a new component upon each render in the parent component, but it does not explain why a TouchableHighlight blinks during its initial render.
Buttons blinking during initial render is acceptable to me - buttons blinking upon any state-change is not.
So I am sufficiently happy now.
Not sure if it's because I'm running a later version, but I found this blinking behavior happens only on the first click.
My solution was putting the code that triggers rerendering in a setTimeout
<TouchableOpacity
onPress={function() {
setTimeout(function() {
_this.setState({myState: 'someValue'})
});
}}
>