getting unexpected token error while declaring global variable? - javascript

I am getting **Unexpected token '&'** error while declaring globle variable .I also tried to stringily it's value but still getting same error why ?
I am doing like this.
<Head>
{
<script type="text/javascript">
var s_pageName2=JSON.stringify('abc:en-us:/lo-form')
</script>
}
</Head>
here is my whole code
https://codesandbox.io/s/long-bird-tgwcv?file=/pages/index.js
Ia m using nextjs framework . I want to create global variable having value this abc:en-us:/lo-form
This is not codesandbox error .I am facing same issue on my local machine

In jsx you cannot just do that, you can use dangerouslySetInnerHTML, but i highly discourage to use it.
<script
dangerouslySetInnerHTML={{
__html: ` var s_pageName2='abc:en-us:/lo-form'`
}}
/>
If you want to store a global variable to reuse in any of your components there are differents ways for achieve that, for example using react Context and expose a custom hook to use wherever you need to.
Example :
_app.js
import { MyProvider} from '../components/MyProvider'
function MyApp({ Component, pageProps }) {
return (
<MyProvider>
<Component {...pageProps} />
</MyProvider>
)
}
export default MyApp
/components/MyProvider :
import React, { useState, useEffect,useContext } from 'react'
export const MyContext= React.createContext(null)
export function MyProvider ({ children }) {
const [myVar, setMyVar] = useState('abc:en-us:/lo-form')
return (
<MyContext.Provider value={{myVar}}>
{children}
</MyContext.Provider>
)
}
export function useApp() {
const value = useContext(MyContext)
return value
}
Then in any other component / page you can just use your hook in this way :
import { useApp } from './components/MyProvider'
const MyPage= () => {
const {myVar} = useApp()
... rest of code
}
This is just an example, you can achieve that in many ways, it depends on your app business logic.

Related

React useContext() not reading context values in?

This is what my code looks like:
Context.js:
const Context = createContext();
export default Context;
ContextProvider.js:
import Context from './Context';
const ContextProvider = () =>
{
....
return(<Context.Provider value={data: 1}>{props.children}</Context.Provider>
}
ParentClass.js:
const ParentClass = () =>
{
...
return(
<div>
...
{boolValue ? (
<ContextProvider>
<ConsumerComponent/>
</ContextProvider>)
</div>)
}
ConsumerComponent.js:
import Context from './Context.js';
const ConsumerComponent = () => {
const contextData = useContext(Context);
...
}
My issue is that ConsumerComponent doesn't seem to be able to access context data; it doesn't render at all when I add the const contextData = useContext(Context); line, and nothing gets logged when I try to print contextData. Where exactly did I go wrong? From my understanding, I followed the necessary steps of creating context + a provider, making sure that the consuming component has a provider as one of its ancestor components, and then accessing the context with useContext().
Considering you want the value prop of the Context Provider to be an object like
{ data : 1 }
you probably forgot the extra curly braces, because the first pair is the JSX syntax to interpret the content as JavaScript instead of a string.
So your value prop on ContextProvider.js file probably should look like this:
<Context.Provider value={{data: 1}}>{props.children}</Context.Provider>

React Context defaultValue returns undefined when no provider is wrapped around the component tree

I have been reading react docs to refresh my concepts. While reading, I came across this statement in context section:
The value argument passed to the function will be equal to the value
prop of the closest Provider for this context above in the tree. If
there is no Provider for this context above, the value argument will
be equal to the defaultValue that was passed to createContext().
So naturally, I created some snippets to actually test the scenario.
My entry point (App.js):
import "./styles.css";
import WearLacoste from "./wearLacoste";
import WearPrada from "./wearPrada";
import OutFitProvider from "./outfitContext";
export default function App() {
return (
<div className="App">
<h1>What to wear?</h1>
<OutFitProvider>
<WearPrada />
</OutFitProvider>
<WearLacoste />
</div>
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Notice that I have two components. These components return a string rendered on the browser, telling which dress to wear. One of the component name <WearPrada /> is wrapped by the provider, the other (<WearLacoste/>) is not, to test the defaultValue scenario.
Following is my context file (outfitContext.js):
import React, { useContext, useState } from "react";
const MyOutfitContext = React.createContext("Lacoste");
//a custom hook to consume context
export const useOutfit = () => {
return useContext(MyOutfitContext);
};
const OutfitContextProvider = ({ children }) => {
const [outfit, setOutfit] = useState("Prada");
return (
<MyOutfitContext.Provider value={{ outfit }}>
{children}
</MyOutfitContext.Provider>
);
};
export default OutfitContextProvider;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
And finally both of my components, which do the exact same thing.
wearPrada.js :
import { useOutfit } from "./outfitContext";
const WearPrada = () => {
const { outfit } = useOutfit();
console.log("Outfit expects Prada", outfit);
return <h1>Wearing {outfit} RN </h1>;
};
export default WearPrada;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
wearLacoste.js :
import { useOutfit } from "./outfitContext";
const WearLacoste = () => {
const { outfit } = useOutfit();
console.log("Outfit expects Lacoste", outfit);
return <h1>Wearing {outfit} RN </h1>;
};
export default WearLacoste;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
My problem is:
The component wrapped in the provider is behaving as expected. It gets the state value initialised in context. But as claimed in the document, the component not wrapped in the provider still gets an undefined value instead of the defaultValue which is Lacoste (see outfitContext.js). Am I doing anything wrong here? Thanks in advance for the help.
It seems that you have mixed the object { outfit: string } with a simple string. The context value is expected to be an object everywhere but when setting the default value you use a string.
I believe what you want is const MyOutfitContext = React.createContext({ outfit: "Lacoste" });

Next.js with Typescript - how to access app.js props and staticProps in functional component

I want to know if it's possible for me to access props passed down from app.js to all Component Page using typescript and functional components. Take a look at app.js and index.ts
app.js:
function MyApp({ Component, pageProps, router }) {
const [message, setMessage] = useState(false)
return (
<Component setMessage={setMessage} key={router.route} {...pageProps} />
)
}
export default MyApp
Index.ts:
function Home({products}): InferGetStaticPropsType<typeof getStaticProps>) {
return (
<div>Home</div>
)
}
export function getStaticProps(){
const products = []
}
I would like to be able to access the setMessage function AND the products from getStaticProps in the index.ts page. I might be doing things the wrong way, thank you for your advice.
It is possible, just like with regular components. Pass your props along with pageProps, like you already do with your setMessage. Here is example. I didn't followed your code precisely, but idea is the same.

Using provider directly from context vs returning it from a function

I'm noticing something new I haven't seen before. It is possible that this isn't specific to this react component.
I tried creating a react context
const MyContext = createContext({...});
Then, I wrote a function to return the provider
const MyProvider = () => {
return <MyContext.Provider value={...} />;
};
<MyProvider /> is a function type React component and <MyContext.Provider /> is an object type React component
When <MyProvider /> is used to wrap components, the React app crashes. However, directly using <MyContext.Provider /> works like I expected.
Since those two aren't the same, is it possible to create a provider component externally and import it elsewhere to use it?
export const MyProvider = (props) => { return ( <MyContext.Provider value={...} /> { props.children } </MyProvider> ); };
We can import it like :
import { MyProvider } from '../path'
use
<MyProvider><YouComponent/></MyProvider>

Global state in React Native

I am developing a React Native application.
I want to save the user id of the person who is logged in and then check if the user is logged in in every single component.
So what I am looking for is something like cookies, sessions or global states.
I have read that I should use Redux, but this seems to be overly complicated and it is very difficult to make it work with react-navigation. It forces me to define actions and reducers for almost everything although the only thing I want is to be able to access a single global state/variable in all components.
Are there any alternatives or should I really re-structure my entire app to use Redux?
I usually create a global.js containing:
module.exports = {
screen1: null,
};
And get the value of the state on the screen
import GLOBAL from './global.js'
constructor() {
GLOBAL.screen1 = this;
}
Now you can use it anywhere like so:
GLOBAL.screen1.setState({
var: value
});
Update since React 16.8.0 (February 6, 2019) introduce Hooks.
it is not mandatory to use external library like Mobx or Redux. (Before Hook was introduce I used both of this state management solutions)
you can create global state just with 10 line Source
import React, {createContext, useContext, useReducer} from 'react';
export const StateContext = createContext();
export const StateProvider = ({reducer, initialState, children}) =>(
<StateContext.Provider value={useReducer(reducer, initialState)}>
{children}
</StateContext.Provider>
);
export const useStateValue = () => useContext(StateContext);
extend your app with global state:
import { StateProvider } from '../state';
const App = () => {
const initialState = {
theme: { primary: 'green' }
};
const reducer = (state, action) => {
switch (action.type) {
case 'changeTheme':
return {
...state,
theme: action.newTheme
};
default:
return state;
}
};
return (
<StateProvider initialState={initialState} reducer={reducer}>
// App content ...
</StateProvider>
);
}
For details explanation I recommend to read this wonderful medium
There are some alternatives to Redux in terms of state management. I would recommend you to look at Jumpsuit and Mobx. However do not expect them to be easier than Redux. State management is mostly a magical thing and most of the gizmo happens behind the scenes.
But anyways if you feel that you need some global state management, it worths your time to master one of the solutions no matter Redux or Mobx or etc. I would not recommend using AsyncStorage or anything hacky for this purpose.
I usually do globals like this:
I creat an globals.js
module.exports = {
USERNAME: '',
};
Something like that to store the username then you just need to import :
GLOBAL = require('./globals');
And if you wanna store the Data, lets say you want to save the username just do :
var username = 'test';
GLOBAL.USERNAME = username;
And there you go , you just need to import GLOBAL on the pages you want and use it, just use if (GLOBAL.username == 'teste').
If you are new to react (as me) and got confused by the first answer.
First, use a component Class
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
walk: true
};
GLOBAL.screen1 = this;
}
render() {
return (
<NavigationContainer>
<Stack.Navigator>
{this.state.walk ? (
<>
<Stack.Screen name="WalkThrough" component={WalkThroughScreen} />
</>
) : (
<Stack.Screen name="Home" component={HomeScreen} />
)}
</Stack.Navigator>
<StatusBar style="auto" />
</NavigationContainer>
)
}
Then you can do in any other component (My components are on /components, global is on root):
import GLOBAL from '../global.js'
GLOBAL.screen1.setState({walk:false})
There appears to be a GLOBAL object. If set in app.js as GLOBAL.user = user, it appears to be available in other components, such as the drawer navigation.
this is an old question but I have a solution that helps me.
To accomplish this, I use what is called a GlobalProvider, essentially provides global data to all components. A lot of this code was learned through YouTube Tutorials so I can not take credit for the ideas. Here is the code,
export const GlobalContext = createContext({});
const GlobalProvider = ({children}) => {
//authInitialState can be whatever you want, ex: {rand: {}, rand2: null}
const [authState, authDispatch] = useReducer(auth, authInitialState);
return (
<GlobalContext.Provider
value={{authState, authDispatch}}>
{children}
</GlobalContext.Provider>
);
};
export default GlobalProvider;
Then you would simply wrap your entire application (usually app.js) with GlobalProvider as so. Ignore my AppNavContainer, that just contains code that routes my pages.
import GlobalProvider from "./src/Context/Provider";
const App: () => Node = () => {
return (
<GlobalProvider>
<AppNavContainer/>
</GlobalProvider>
);
};
From here on you are able to change the authState with a reducer of some sort, I will not provide that code since it is huge, but look at Soullivaneuh's example on the reducer above.
NOW to the good part, of how to access your state. It is simple, in any component you wish, simply follow a similar structure like this. Notice that I have {data} as it will allow you to see the state.
const {
authState: {data},
} = useContext(GlobalContext);
console.log("Data:", data)
If anyone can correct me where I went wrong, I'd appreciate it as well.
Same as #Brunaine suggested, but I import it only in the App.js and can use it in all the screens.

Categories