Why is below code not working?
It returns false even when I set inverted to true;
it also logs hit so it does reach.
import React, { useEffect, useState } from 'react';
import { ComponentProps } from 'react';
import { useHistory } from 'react-router-dom';
type Props = {
} & ComponentProps<'div'>;
export function HeaderMaster({
...props
}: Props) {
const [inverted, setInverted] = useState(false);
const history = useHistory()
useEffect(() => {
setInverted(true); // this does work
history.listen((location) => {
console.log(location.pathname);
if (location.pathname === '/bestellen') {
setInverted(true); // this does not
console.log('hit');
}
else {
setInverted(false);
}
})
},[history]);
useEffect(() => {
console.log(inverted);
},[inverted])
return (
<>
</>
);
}
Related
I m getting error in TwitterProvider how to fix that
import '../styles/globals.css'
import type { AppProps } from 'next/app'
import { TwitterProvider } from '../context/TwitterContext'
import '../lib/hexStyles.css'
import React from 'react'
function MyApp({ Component, pageProps }: AppProps) {
return (
<TwitterProvider>
<Component {...pageProps} />
</TwitterProvider>
)
}
export default MyApp
error image
TwitterContext Code
import { createContext, useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import { client } from '../lib/client'
export const TwitterContext = createContext()
export const TwitterProvider = ({ children }) => {
const [appStatus, setAppStatus] = useState()
const [currentAccount,setCurrentAccount] = useState('')
useEffect(() => {
checkIfWalletIsConnected()
}, [])
const checkIfWalletIsConnected = async () => {
if (!window.ethereum) return
try {
const addressArray = await window.ethereum.request({
method: 'eth_accounts',
})
if (addressArray.length > 0) {
setAppStatus('connected')
setCurrentAccount(addressArray[0])
} else {
router.push('/')
setAppStatus('notConnected')
}
}catch (error) {
console.log(error)
}
}
const connectToWallet = async () => {
if(!window.ethereum) return setAppStatus('noMetaMask')
try {
setAppStatus('loading')
const adressArray = await window.ethereum.request({
method: 'eth_requestAccounts',
})
if (addressArray.length > 0) {
setCurrentAccount(addressArray[0])
} else {
router.push('/')
setAppStatus('notConnected')
} catch (error) {
setAppStatus('error')
}
}
return (
<TwitterContext.Provider value={{appStatus, currentAccount,
connectToWallet }}
>
{children}
</TwitterContext.Provider>
)
}
Example code can be found below...
(Parent) App.tsx
import React, { useRef } from 'react';
import { Switch } from "react-router-dom";
import axios, { AxiosResponse } from 'axios';
import { AdminRoute } from './auth/protectedRoutes';
import Home from './views/Home';
export interface Data {
id: number;
name: string;
}
function App(): JSX.Element {
// variables
const searchDebouncerRef = useRef(false);
const [data, setData] = useRef<Array<Data>>([]);
// functions
async function updateData(searchString?: string | null) {
try {
const response: AxiosResponse<Array<Data>> = searchString
? await axios.get(`https://example.com/Api/Data$filter=contains(name, ${searchString})`)
: await axios.get('https://example.com/Api/Data');
if (searchDebouncerRef.current) {
return;
}
setData(response.data);
catch (e) {
console.log(e);
}
}
async function initData() {
try {
await updateData();
catch (e) {
console.log(e);
}
}
// setup
useEffect(() => {
initData();
}, []);
// render
return (
<>
<Switch>
<AdminRoute path="/">
<Home ref={searchDebouncerRef} updateData={updateData} data={data} />
</AdminRoute>
</Switch>
</>
)
}
export App;
(Child) Home.tsx
import React, { forwardRef } from 'react';
import { Data as DataRow } from '../App';
import Search from '../components/Search';
interface PROPS {
updateData: (searchString?: string | null) => void;
data: Array<DataRow>;
}
const Home: React.FC<any> = forwardRef(
({ updateData, data }: PROPS, ref) => {
return (
<div>
<Search isSearchDebouncingRef={ref} updateData={updateData} />
{data.map((row: DataRow) => ({
<p key={row.id}>{row.name}</p>
}))}
</div>
);
}
);
(Grandchild) Search.tsx
import React, { ChangeEvent, useCallback, useState } from 'react';
import { debounce } from 'lodash';
interface PROPS {
updateData: (searchString?: string | null) => void;
isSearchDebouncingRef: ???? // <-----------------------------------------------------
}
function Search({ updateData, isSearchDebouncingRef }: PROPS): JSX.Element {
// variables
const [searchText, setSearchText] = useState('');
const [searchDebouncerHasCompleted, setSearchDebouncerHasCompleted] = useState(false);
const searchDebouncer = useCallback(
debounce(() => {
setSearchDebouncerHasCompleted(true);
isSearchDebouncingRef.current = false;
}, 3000),
[]
);
// functions
function handleSearch(event: ChangeEvent<HTMLInputElement>) {
setSearchText(event.target.value);
isSearchDebouncingRef.current = true;
searchDebouncer();
}
// setup
useEffect(() => {
if (searchDebouncerHasCompleted) {
setSearchDebouncerHasCompleted(false);
updateData(searchText || null);
}
}, [searchDebouncerHasCompleted]);
// render
return <input type="text" value={searchText} onChange={(e) => handleSearch(e)} />; // ToDo: add icons(search, spinner, clear)
}
The grandchild file is where I am having trouble figuring out how to identify the type for the ref(see interface PROPS). Also the child file I would like to replace any, with the proper type if possible.
I'm trying to use the useSnack hook from notistack library but I keep getting this error
TypeError: Cannot destructure property 'enqueueSnackbar' of 'Object(...)(...)' as it is undefined.
Here is the code:
import React, { useContext, useEffect } from "react";
import AlertContext from "../context/alert/alertContext";
import { SnackbarProvider, useSnackbar } from "notistack";
const Alerts = (props) => {
const alertContext = useContext(AlertContext);
// This line below is where the error seems to be
const { enqueueSnackbar } = useSnackbar();
useEffect(() => {
alertContext.msg !== "" &&
enqueueSnackbar(alertContext.msg, {
variant: alertContext.type,
});
}, [alertContext]);
return <SnackbarProvider maxSnack={4}>{props.children}</SnackbarProvider>;
};
export default Alerts;
useSnackbar hook accessible anywhere down the tree from SnackbarProvider.
So you cannot use it in the same component as SnackbarProvier.
import AlertContext from "../context/alert/alertContext";
import { SnackbarProvider } from "notistack";
const Alerts = (props) => {
const alertContext = useContext(AlertContext);
const providerRef = React.useRef();
useEffect(() => {
alertContext.msg !== "" &&
providerRef.current.enqueueSnackbar(alertContext.msg, {
variant: alertContext.type,
});
}, [alertContext]);
return <SnackbarProvider ref={providerRef} maxSnack={4}>
{props.children}
</SnackbarProvider>;
};
export default Alerts;
Wrap you index file with SnapBar provider:
index.js
import { SnackbarProvider } from "notistack";
const Index = () => (
<SnackbarProvider maxSnack={1} preventDuplicate>
index
</SnackbarProvider>
)
export default Index
jsx file
import { useSnackbar } from "notistack";
const Logs = () => {
const { enqueueSnackbar } = useSnackbar();
const handler = () => {
enqueueSnackbar(`Successful.`, { variant: "success" });
};
return <span onClick={handler}>"Logs loading"</span>;
};
export default Logs;
I wrote here is the code
import React, { FC, Fragment, useEffect } from "react";
import { createBrowserHistory } from "history";
const history = createBrowserHistory();
const HandlerErr: FC<{ error: string }> = ({ error }) => {
useEffect(()=>{
const time = setTimeout(() => {history.push(`/`)}, 2000);
return(()=> clearTimeout(time));
},[error])
return (
<Fragment>
<div>{error}</div>
<div>{"Contact site administrator"}</div>
</Fragment>
);
};
I use the HandlerErr component to redirect. but for some reason it doesn't work history.push (/).I took a video
You need to use history form the react-router-dom
like
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
class Test extends Component {
render () {
const { history } = this.props
return (
<div>
<Button onClick={() => history.push('./path')}
</div>
)
}
}
export default withRouter(Test)
import React, { FC, useEffect } from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
interface OwnProps {
error: string;
}
type Props = OwnProps & RouteComponentProps<any>;
const HandlerErr: FC<Props> = ({ error, history }) => {
useEffect(() => {
const timeout = setTimeout(() => {
history.push(`/`);
}, 2000);
return () => {
clearTimeout(timeout);
};
}, [error]);
return (
<>
<div>{error}</div>
<div>Contact site administrator</div>
</>
);
};
export default withRouter(HandlerErr);
I am new to react and typescript.
I have a component Err.
I want to redirect it using react router 5 ?.
import React, { FC, Fragment, useEffect } from "react";
const Err: FC<{ error: string }> = ({ error }) => {
useEffect(()=>{
const time = setTimeout(() => {???(`/`)}, 2000);
return(()=> clearTimeout(time));
},[error])
return (
<Fragment>
<div>{error}</div>
<div>{"Contact site administrator"}</div>
</Fragment>
);
};
I don't know how to react router 5.
But if you use react router 4.
import React, { FC, Fragment, useEffect,useState } from "react";
import { Redirect } from "react-router";
const HandlerErr: FC<{ error: string }> = ({ error}) => {
const [booleURL, setBooleURL] = useState(false);
useEffect(()=>{
const time = setTimeout(() => {setBooleURL(true)}, 2000);
return(()=> clearTimeout(time));
},[error])
return (
<Fragment>
{ booleURL && <Redirect to="/"/>}
<div>{error}</div>
<div>{"Contact site administrator"}</div>
</Fragment>
);
};
or
import React, { FC, useEffect } from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
interface OwnProps {
error: string;
}
type Props = OwnProps & RouteComponentProps<any>;
const HandlerErr: FC<Props> = ({ error, history }) => {
useEffect(() => {
const timeout = setTimeout(() => {
history.push(`/`);
}, 2000);
return () => {
clearTimeout(timeout);
};
}, [error]);
return (
<>
<div>{error}</div>
<div>Contact site administrator</div>
</>
);
};
export default withRouter(HandlerErr);