Custom header on parent stack navigator with react-navigation - reactjs

I have an app using react-navigation which has basically this structure:
StackNavigator -> BottomTabBarNavigator -> (each tab) StackNavigator
I am trying to add a global button component, it lived on the TabBar, but there are sibling views that would hide it when they are shown. So, ultimately the best place to put it would be on the parent StackNavigator, however, when I try to put the custom header on the navigationOptions of the parent StackNavigator, I get the error
Unexpected token, expected "</>/<=/>="
And it points to the { in header: props => <ConversationBuble {...props} /> on the navigationOptions object. Which I dont understand, as I am able to do this on the child most StackNavigator. Can anyone help me understand what the problem is here and why I am unable to inject the custom header at the parent level?

Related

React Context always returns EMPTY

I have a Search parent component and a SideBar child component, I am trying to get context in SideBar, but everytime it returns empty.
I followed the tutorial exactly like: https://itnext.io/manage-react-state-without-redux-a1d03403d360
but it never worked, anyone know what I did wrong?
Here is the codesandbox link to the project: https://codesandbox.io/s/vigilant-elion-3li7v
I wrote that article.
To solve your specific problem:
When using the HOC withStore you're injecting the prop store into the wrapped component: <WrappedComponent store={context}.
The value of the prop store is an object that contains 3 functions: get, set, and remove.
So, instead of printing it, you should use it. For example this.props.store.get("currentAlbums") or this.props.store.set("currentAlbums", [album1, album2]).
This example is forked by your code: https://codesandbox.io/s/nameless-wood-ycps6
However
Don't rewrite the article code, but use the library: https://www.npmjs.com/package/#spyna/react-store which is already packed, tested, and has more features.
An event better solution is to use this library: https://www.npmjs.com/package/react-context-hook. That is the new version of the one in that article.
This is an example of a sidebar that updates another component content: https://codesandbox.io/s/react-context-hook-sidebar-xxwkm
Be careful when using react context API
Using the React Context API to manage the global state of an application has some performance issues, because each time the context changes, every child component is updated.
So, I don't recommend using it for large projects.
The library https://www.npmjs.com/package/#spyna/react-store has this issue.
The library https://www.npmjs.com/package/react-context-hook does not.
You pass the store as a prop, so to access it, you need this.props.store in your SideBar.
Not this.state.store
Create a wrapping App component around Search and Sidebar:
const App = props => (
<div>
<Search />
<SideBar />
</div>
);
export default createStore(App);
Now you can manipulate state with set and get that you have available in child components Search and Sidebar.
In Search component you can have something like:
componentDidMount() {
this.props.store.set("showModal", this.state.showModal);
}
also wrapped with withStore(Search) ofc.
and in SideBar you can now call:
render() {
return (
<div>
{"Sidebar: this.state.store: ---> " +
JSON.stringify(this.props.store.get("showModal"))}
}
</div>
);
}
and you will get the output.

Header grows after rendering inside react native application

I am creating an application using react native/expo, using react-navigation for navigation.
I need a bottom tab navigator, and for every tab i need a stack navigator. I have followed the example on the website and it functionally works fine. (https://reactnavigation.org/docs/en/tab-based-navigation.html)
Everytime i select a different stack from on the tab navigator the new header renders (great)! but it then grows as if its adding padding to compensate for the status bar.
is there any way to solve this?
thankyou.
You can add the following to remove extra statusbar height for all screens in a navigator:
const MyStack = createStackNavigator({
// screens
}, {
defaultNavigationOptions: {
headerStatusBarHeight: 0
}
});
Or you can do it per screen:
static navigationOptions = {
headerStatusBarHeight: 0
}
You can also specify a custom value if you need.

How to setup React Router <Link> inside a Datatables.net Cell?

I have a datatables table (https://datatables.net) initialized like this:
$('#example').DataTable({
data: data,
columns: [{
title: "Database ID",
data: 'database_id',
render: function (data, type, row) {
return '<NavLink to="/shop">'+ data +'</NavLink>';
}
}]
});
The NavLink that i have in the code is supposed to render a database cell as a clickable link because of React-Router (This whole function is inside a React component), but the link is not rendering when i run the code.
What i ultimately want is the ability to click on a database cell that will take me to another component by routing into a link like "/shop/id" but i am stuck in it for a long time. Help!
I was facing the same issue and below solution is working for me.
You can directly add anchor tag with href to the path where you want to route upon on the click. But, it will reload your application.
To avoid reloading of the application, try below solution.
When you're initializing the columns dynamically, you can add below code for the column where you want to have a link.
fnCreatedCell: (nTd, data) => ReactDOM.render(
<a
onClick={() => handletableclick(data, props)}>
{data}
</a>, nTd)
Add handletableclick() function/method in your file to handle click event and programmatically through history push the path where you want to route upon the click
function handletableclick(data, props) {
props.history.push("/pathToRoute=" + data);
}
Also,in above code to access history from props, you will need to enclose your component with withRouter
like below :
export default withRouter(YourComponentName);

Link in Infobox using react-google-maps causes page reload

I'm not able to put a react-router-dom Link inside of a react-google-maps InfoBox without causing a full page reload.
Here's the code for my InfoBox:
import InfoBox from 'react-google-maps/lib/components/addons/InfoBox'
import { Link } from "react-router-dom";
class MyInfoBox extends Component {
...
const options = {
enableEventPropagation:false,
position: new google.maps.LatLng(loc.latitude, loc.longitude)
};
render(){
return (
<InfoBox options={options}>
<Link to={`/location/${loc.id}`}>Go To Location</Link>
</InfoBox>
);
}
}
All Links in my app work correctly, except for this one.
When the "Go To Location" link is clicked, a full-page reload is caused. I've tried to diagnose by following this issue: https://github.com/tomchentw/react-google-maps/issues/258, but I really don't know enough about the react router v4 to find out if the context contains the router object. Changing the value of enableEventPropagation does not change the behavior.
If anyone can help me understand why the Link is causing a page reload, I would really appreciate it.
Thank you in advance!
Try removing onClick prop in <GoogleMap> component and add enableEventPropagation: true to <InfoBox> options.
For me the issue was that <GoogleMap> onClick event was used to remove <InfoBox> when user clicks outside it. But turns out it is called also inside <InfoBox> so basically it was removing <InfoBox> with the <Link> inside it, before handling <Link> click.

onsen react navigator pushpage overwrites last page

In a project, my intention is to use only one Navigator element to handle all page navigation.
There is one singleton appState all over the code, and navigator is member of that, it gets initialized by the outermost App component.
ReactDOM.render(
<App/>,
document.getElementById('app')
);
The navigator is initiated by:
initialRoute = {
component: LoginPage,
props: {
}};
and
<Ons.Navigator
initialRoute={this.initialRoute}
renderPage={this.renderPage.bind(this)}
/>
and
renderPage(route: Route, navigator: typeof Ons.Navigator) {
const props: any = route.props || {};
if (appState.navigator == null) {
appState.navigator = navigator;
}
props.navigator = appState.navigator;
return React.createElement(route.component, route.props);
}
correctly with initialRoute. When I call pushPage(newRoute), the newRoute is apparently added, when checked at the time of addition. That is, I get the following right after pushing newRoute:
LoginPage
HomePage
However, a subsequent call to pushPage(someOtherRoute) yields
LoginPage
SomeOtherRouteComponent
I would expect
LoginPage
HomePage
SomeOtherRouteComponent
I have verified that there is no issue with synchronization etc, when I push the route object to an aside list, I get everything without any loss. But just pushPage is not working as I expect.
Any ideas, or missing something obvious? The snippets are TS.
It appears that any error during page load is caught by Navigator, and that causes the page to be not added into routes (but the page is still navigated to).
I have filed an issue on github with a workaround. An alternative workaround is to make sure that there are no JS errors during page load, which may not be 100% the case given 3rd party modules are present.

Resources