React Native rendering same route - javascript

I want to change routes on button press in React Native. In my SplashContainer component this is the method I'm running:
handleToSignUp = () => {
console.log("Running handleToSignUp")
this.props.navigator.push({
signUpForm: true
});
}
My Navigator component looks like this
export default class NimbusNavigator extends Component {
static propTypes = {
isAuthed: PropTypes.bool.isRequired
}
renderScene = (route, navigator) => {
console.log(route);
console.log(navigator);
// Keeps track of whether user is Authed or not.
if (this.props.isAuthed === false && route !== 'signUpForm') {
return <SplashContainer navigator={navigator}/>
} else if (route === 'signUpForm') {
return <SignUpForm navigator={navigator} />
}
return <FooterTabsContainer navigator={navigator} />
}
configureScene = (route) => {
return Navigator.SceneConfigs.FloatFromRight
}
render () {
return (
<Navigator
configureScene={this.configureScene}
renderScene={this.renderScene}
/>
)
}
}
If route is not equal to 'signUpForm' shouldn't code skip to the else if statement and render <SignUpForm/> component?
Thanks!

There are a few ways to get this working, but the main thing to remember is that everything passed to navigator.push({ // properties of the route object }) become properties of the route object.
For instance, if you keep your handleSignUp method the way it is, you would need to rewrite your renderScene method like so:
renderScene = (route, navigator) => {
if (this.props.isAuthed === false && !route.signUpForm) {
return <SplashContainer navigator={navigator}/>
} else if (route.signUpForm) {
return <SignUpForm navigator={navigator} />
}
return <FooterTabsContainer navigator={navigator} />
}
You could also rewrite your handleSignUp method like this:
handleToSignUp = () => {
this.props.navigator.push({
title: 'handleSignUpForm'
});
}
And renderScene like this:
renderScene = (route, navigator) => {
if (this.props.isAuthed === false && route.title !== 'signUpForm') {
return <SplashContainer navigator={navigator}/>
} else if (route.title === 'signUpForm') {
return <SignUpForm navigator={navigator} />
}
return <FooterTabsContainer navigator={navigator} />
}

Related

Add Class On Page Reload In Next JS

I'm kind of new w/ react and nextjs. How can insert a script in a component to add class in when the page reload? It seems like the code below don't work because the page is not yet rendered when I add the class for the body tag.
const ModeToggler = (props: Props) => {
// ** Props
const { settings, saveSettings } = props
const handleModeChange = (mode: PaletteMode) => {
saveSettings({ ...settings, mode })
}
const handleModeToggle = () => {
if (settings.mode === 'light') {
handleModeChange('dark');
document.body.classList.add('mode-dark');
} else {
handleModeChange('light');
document.body.classList.remove('mode-dark');
}
}
// This will not work because the page is not rendered yet right?
if (settings.mode === 'light') {
document.body.classList.add('mode-dark');
} else {
document.body.classList.remove('mode-dark');
}
return (
<IconButton color='inherit' aria-haspopup='true' onClick={handleModeToggle}>
{settings.mode === 'dark' ? <WeatherSunny /> : <WeatherNight />}
</IconButton>
)
}
export default ModeToggler
In your case, since the class is dependent on the prop settings
I would suggest you use a useEffect with a dependency of that prop. So not only will it retrieve the value and apply the style on render, but also re-render/apply style each time the prop changes.
const ModeToggler = (props: Props) => {
// ** Props
const { settings, saveSettings } = props
const handleModeChange = (mode: PaletteMode) => {
saveSettings({ ...settings, mode })
}
const handleModeToggle = () => {
if (settings.mode === 'light') {
handleModeChange('dark');
document.body.classList.add('mode-dark');
} else {
handleModeChange('light');
document.body.classList.remove('mode-dark');
}
}
useEffect(() => {
if (settings.mode === 'light') {
document.body.classList.add('mode-dark');
} else {
document.body.classList.remove('mode-dark');
}
}, [settings.mode])
return (
<IconButton color='inherit' aria-haspopup='true' onClick={handleModeToggle}>
{settings.mode === 'dark' ? <WeatherSunny /> : <WeatherNight />}
</IconButton>
)
}
export default ModeToggler
you can detect if your page is reload or not using window.performance
for more info https://developer.mozilla.org/en-US/docs/Web/API/Performance/getEntriesByType
useEffect(()=>{
let entries = window.performance.getEntriesByType("navigation");
if(entries[0]=="reload"){
// add class to an element;
}
},[])

same condition statement on multiple pages in next js

I am using next js in my project
when i fetch from my server using useswr hook then there is certain condition to return on the page for example
dashboard.js
import InnerNavbar from "../components/InnerNavbar";
import DashboardLoadingSkeleton from "../components/DashboardLoadingSkeleton";
import DashBoardData from "../components/DashBoardData";
import useSWR, { mutate } from "swr";
const fetcher = async () => await fetch(`${process.env.NEXT_PUBLIC_URL}/fetchchallenges`, {
method: "POST",
credentials: 'include'
}).then((res) => res.json());
const dashboard = () => {
const { data, error } = useSWR("/dashboard", fetcher, { dedupingInterval: 40000 });
if (!data) {
if (!data.Errors) {
return (<><InnerNavbar /><DashBoardData data={data} mutate={mutate} /></>);
} else if (data.Errors === "Not Approved") {
return (<>{location.replace('/notapproved')} <center><h1>Not Approved By Admin</h1></center></>)
}else {
return (<>{location.replace('/logout')} <center><h1>Redirecting...</h1></center></>)
}
} else {
return (
<>
<InnerNavbar />
<DashboardLoadingSkeleton />
</>
)
}
};
export default dashboard;
now i want to need this same conditional statement in multiple pages to return but i don't known how to create a separate function for that.
I think you can use react Higher-Order Components
here is sth that I made:
import useSWR, { mutate } from "swr";
const fetcher = async () => await fetch(`${process.env.NEXT_PUBLIC_URL}/fetchchallenges`, {
method: "POST",
credentials: 'include'
}).then((res) => res.json());
const withSwrData = ({Component,endpoint}) => {
const { data, error } = useSWR(endpoint, fetcher, { dedupingInterval: 40000 });
if (!data) {
if (!data.Errors) {
return (<Component data={data} mutate={mutate} />);
} else if (data.Errors === "Not Approved") {
return (<>{location.replace('/notapproved')} <center><h1>Not Approved By Admin</h1></center></>)
}else {
return (<>{location.replace('/logout')} <center><h1>Redirecting...</h1></center></>)
}
} else {
return (
<>
<Component />
</>
)
}
};
export default withSwrData;
and use it in dashboard in this way :
import InnerNavbar from "../components/InnerNavbar";
import DashboardLoadingSkeleton from "../components/DashboardLoadingSkeleton";
import DashBoardData from "../components/DashBoardData";
import withSwrData from "../withSwrData"
const dashboard = ({data,mutate}) => {
return (<>
<InnerNavbar />
{data ? <DashBoardData data={data} mutate={mutate} /> : <DashboardLoadingSkeleton /> }
</>)
};
export default withSwrData(dashboard,"/dashboard");

Imperative version of next/router not working with Semantic-UI-React?

According to the Next.js docs
You can also do client-side page transitions using next/router:
import Router from 'next/router'
function ReadMore() {
return (
<div>
Click <span onClick={() => Router.push('/about')}>here</span> to read more
</div>
)
}
export default ReadMore
I am essentially extrapolating that to my own example with Sematic-UI-React:
This my current behavior which is obviously is not desired.
You can see at some point the <Link/> component or perhaps its the <Menu.Item/> falls out of sync.
This is how the <Menu.Item/> works as per their docs.
You can see how snappy it's behaving, but that's with the <Link/> tag commented out...
This is the greater HOC.
var comparator;
const GenericIsUserLoggedInLink = React.memo(({ isHomeButton, isLoggedIn, logOutUser, route, anchorText, mobile, name, active, handleItemClick }) => {
comparator = (prevProps, nextProps) => {
if (prevProps.isHomeButton !== nextProps.setProps.isHomeButton) {
return true;
}
if (prevProps.isLoggedIn !== nextProps.setProps.isLoggedIn) {
return true;
}
if (prevProps.mobile !== nextProps.setProps.mobile) {
return true;
}
if (prevProps.name !== nextProps.setProps.name) {
return true;
}
if (prevProps.active !== nextProps.setProps.active) {
return true;
}
return false;
}
function currentNav(route, name, active, handleItemClick) {
// console.log("handleItemClick ", handleItemClick);
// console.log("active ", active);
// console.log("name ", name);
/* This is where I extrapolated their imperative version */
function MyLink({children, route}) {
console.log(`route ${route}`)
return (
<>
<span onClick={() => Router.push(route)}>{children}</span>
</>
)
}
return (
<MyLink route={route}>
<Menu.Item
to={route}
key={name}
name={name}
active={active == name}
onClick={(e) => {
handleItemClick(e, { name });
}
}
>
</Menu.Item>
</MyLink>
);
}
if (isHomeButton) {
return currentNav(route, name, active, handleItemClick)
}
if (isLoggedIn) {
if (anchorText === undefined) {
return <Link href="/"><a onClick={() => logOutUser()}>Log out!</a></Link>
}
else if (mobile) {
return currentNav(route, name, active, handleItemClick)
}
else if (!(mobile)) {
return currentNav(route, name, active, handleItemClick)
}
else if (anchorText) {
return <Link href={route}><a>{anchorText}</a></Link>
}
} else {
if (route === "/login") {
return <Link href="/login"><a>Log in!</a></Link>
}
return null
}
}, comparator);
Any help would be appreciated!

Nothing displayed from if else statement in map return

I am trying to use if else within a map return but nothing is being returned. I don't get any error messages and the if is working because I can console.log from it. I'm not sure what the error is because the code looks fine.
import React, { Component } from 'react'
import { Consumer } from '../context'
import PollCard from './PollCard'
class Polls extends Component {
render() {
return (
<Consumer>
{value => {
const { polls } = value
if (polls === undefined || polls.length === 0) {
return (<p>Polls loading</p>)
} else {
polls.map(poll => {
const current = poll.create_at
const next = poll.create_at
if (Date.parse(next) > Date.parse(current)) {
return (
<div>
<h1>{poll.create_at}</h1>
<PollCard key={poll.id} poll={poll} />
</div>
)
}
return (
<div>
<h1>test</h1>
<PollCard key={poll.id} poll={poll} />
</div>
)
})
}
}}
</Consumer>
)
}
}
export default Polls;
You need to return polls.map in your else statement.
The first statement in your map function will never be true. current & next are both equal to poll.created_at so next can't be greater than current.
import React, { Component } from 'react';
import { Consumer } from '../context';
import PollCard from './PollCard';
class Polls extends Component {
render() {
return (
<Consumer>
{(value) => {
const { polls } = value;
if (polls === undefined || polls.length === 0) {
return <p>Polls loading</p>;
}
return polls.map((poll) => {
const current = poll.create_at;
const next = poll.create_at;
/* This will never be true - they are both equal because they both equal poll.created_at */
if (Date.parse(next) > Date.parse(current)) {
return (
<div>
<h1>{poll.create_at}</h1>
<PollCard key={poll.id} poll={poll} />
</div>
);
}
return (
<div>
<h1>test</h1>
<PollCard key={poll.id} poll={poll} />
</div>
);
});
}}
</Consumer>
);
}
}
export default Polls;

ReactJS Onclick not working for generated elements

I am generating a list of elements with:
LeftPanel.js
if (this.state.trader_or_team == 'trader') {
itemList = users.map(u => <User key={u.id} user={u}
selected={this.props.selected_trader && this.props.selected_trader.id == u.id}
onClick={this.props.handleTraderSelection.bind(this, u)}
/>);
} else {
itemList = teams.map(t => <Team key={t.id} team={t}
selected={this.props.selected_team && this.props.selected_team.id == t.id}
onClick={this.props.handleTeamSelection.bind(this, t)}
/>)
}
handleTeamSelection/handleTraderSelection are in the parent component:
TargetManager.js
handleTraderSelection(selected_trader) {
console.log('test')
this.setState({
selected_trader
});
}
handleTeamSelection(selected_team) {
this.setState({
selected_team
});
}
They are passed down as props:
<LeftPanel
handleTraderSelection={::this.handleTraderSelection}
handleTeamSelection={::this.handleTeamSelection}
/>
And rendered:
LeftPanel.js
return(
<div className="item-container">
{itemList}
</div>
)
When I click on any of the elements nothing happen at all. What is going wrong?
It appears to break when I bind something to it, in the render method of LeftPanel.js:
render() {
this.props.handleTraderSelection()
...
Works,
render() {
this.props.handleTraderSelection.bind(this)
...
Does not work.
Try binding the handleTraderSelection and handleTeamSelection function like
handleTraderSelection = (selected_trader) => {
console.log('test')
this.setState({
selected_trader
});
}
handleTeamSelection = (selected_team) => {
this.setState({
selected_team
});
}
I have been following the conventional method to call the parent function like
handleTraderSelection = (value) => {
this.props.handleTraderSelection(value);
}
handleTeamSelection= (value) => {
this.props.handleTeamSelection(value);
}
if (this.state.trader_or_team == 'trader') {
itemList = users.map(u => <User key={u.id} user={u}
selected={this.props.selected_trader && this.props.selected_trader.id == u.id}
onClick={this.handleTraderSelection.bind(this, u)}
/>);
} else {
itemList = teams.map(t => <Team key={t.id} team={t}
selected={this.props.selected_team && this.props.selected_team.id == t.id}
onClick={this.handleTeamSelection.bind(this, t)}
/>)
}
and it works for me well.
I was missing my onClick for my elements...:
export default class User extends Component {
render() {
return (
<div onClick={this.props.onClick}>
...

Categories

Resources