Passing var from outside react - build error - reactjs

Im passing some variables from outside of my react app (create-react-app) and it works fine on front end but I get build errors in webpack/npm? Because the variable doesn't exist (or it doesn't know about it).
I have this var in a var preloadTab = "x"; in my .net page
49:31 error 'preloadTab' is not defined no-undef
54:14 error 'preloadMsg' is not defined no-undef
I tried putting an undefined check around it but think its just flagging that instead now:
if (typeof preloadMsg !== 'undefined') {
if (preloadMsg != ""){
console.log(preloadMsg, "preloadMsg")
this.setState({preloadMsg: preloadMsg})
}
}
Whats the best way to pass a variable from outside the react "ecosystem" outside of an ajax call?

Sounds like you can make use of either getInitialState or by setting defaultProps for the component. Would either of those work for your case?
As azium already stated in a comment, another option would be to pass the data in as a prop. If you don't have access to the component, then you can save it as a global value either via window or using a constants file. Having a constants file is common in React apps and I would suggest this route over using window.

Related

Web Share API availability check causes typescript warning

I have a react functional component where I store a state value to define if the Web Share API is available in the users browser. I do that by initializing the state with:
const [canShare, setCanShare] = useState<Boolean>(navigator.share ? true : false)
This works as expected, however I'm getting the following typescript error:
This condition will always return true since this function is always defined. Did you mean to call it instead?
What I don't fully understand is why the typescript error thinks that function is always defined? In browsers that don't support the Web Share API (i.e. Chrome on MacOS) that function is undefined.
I know I can safely ignore this warning, but I'm curious if there is a way to not receive this error?
The only work around I came up with was to call navigator.share() in a try-catch block and set the bool from that, but that seems really excessive.

How to prevent refresh of list over API after drag & drop with beautiful DND?

I simulated my Context + DND problem in https://codesandbox.io/s/adoring-booth-33vqo . I have other components which will be added to this example and I will use a Context hook to share values across the page.
After the initial render, everything looks fine. The idea of the list is to change the order within itself and when ones changes the order with drag-drop, it throws an "Invalid Hook" error.
So the (first) real question is, what is triggering this error which is linked to the line
const { lang1Library, updateLang1Library } = useContext(LangContext)
;
Thanks in advance for your help.
Geo
It's not a good approach to provide a link for the whole project even if it is small. But I had a quick look and there's at least one thing you're doing wrong:
// DragEndFct.js
export default function DragEndFct(result, libName) {
const { lang1Library, updateLang1Library } = useContext(LangContext);
This is not React component, but it uses a hook - and it is wrong. Hooks have a special meaning in React and should be used properly (Rules of Hooks).
You can't use hooks inside regular functions and expect them to work. That is why you are getting that error.
So, there are many ways you can try to fix this. For instance, DragEndFct is a regular function, you can declare more arguments and pass stuff you get from context:
// you are using it in components right ?
function DragEndFct(result, libName, param3, param4) {}
// so you probably have access to the context there
// and can pass data from the context when you call it.
// something like this
onDragEnd={function (result) {
console.log();
DragEndFct(result, StaticVars.LANG1_LIBRARY_NAME, lang1Library, updateLang1Library);
}}
You could even make DragEndFct to be a React component - it can just return null (which means no UI will be rendered) but in that case you will have hooks and all other stuff there. It really depends on what you need and how you will use it.

cannot read property of 'map' undefined - typescript react

I'm trying to create a simple app with react using typescript, its my first time using typescript with context api and to this level so I'm having issues I don't quite understand. my main issues is my .map doesn't seem to me working and for some reason and gives me the error I provided in the title and when I click the Add catergory button in the Main.tsx file nothing seems to work there either? Any ideas? I've created a sandbox below.
Any help would be appreciated please, thank you.
https://codesandbox.io/s/smoosh-violet-j1gjz?file=/src/components/CategoryList.tsx
Your error simply mean that "state" is undefined.
const { state } = useContext(Store) || [];
Mean that you want to extract the property named state from the result of "useContext(Store) || [];"
In the case where you have an empty Array it make no sens, you array will not have a property state. So you can change by
const state = useContext(Store) || [];
I dont know what "useContext(..)" is suppose to return, but at least it correct the error when you have an empty array

Global es6 module to store constants in react app - prevent garbage collection

I would like to store some variables inside a module (export) to be used as constants though out my react app. I would like to avoid context because there is no need for components to re-render and also I need those constants to be used outside my react components.
Where should I do it (where to import it), in order to prevent garbage collection?
One idea I have is to import and re-export it on top of my root component.
EDIT:
To be more precise, there will be a component that will set the constant once (mutate the variable), so that other components or files can access it.
So, what you will need is some sort of setter/getter pattern. Though I mostly don't recommend it unless you know what you are doing, because React won't re-render if the variable changes and because of that you need to be sure the variable is set before it is used.
You should have something like the example below in order for it to work the way you want. You can find an example of it working on this Codesandbox.
export let MY_VARIABLE = "";
export const setMyVariable = value => (MY_VARIABLE = value);
PS: I've added some console.log to the code in order for you to see how the import/get/set behaves.
After digging more into this I found that es6 module spec states:
When import your module it gets loaded => parsed => evaluated and cached (singleton). It also says that when you import modules its value is passed by reference (aka assignment). I didn't find anything mentioning when or how es6 modules are unloaded from that cache.
So that means, when you import a module once, it is there for as long as the program is running, and all modules access its values directly.
reference
https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/
https://medium.com/#mivanichok/understanding-es6-modules-in-depth-article-b49612926e39
You can create an config.js inside src folder and write the your constant variable like
//config.js
module.exports = {
CONST_VAR : 'const value',
}
import config.js in your component and use it

ReactJS external library

Hi I am quite new to reactjs but I started to understand few things. But this one giving me a headache, I have a small reactjs component that will be added in an existing site. The problem is inside my component I wanted to use a function in a JS file that is declared masterpage of the site. The name of the function I want to access is "SPClientPeoplePicker_InitStandaloneControlWrapper", so whenever I build my component I get the following error :
'SPClientPeoplePicker_InitStandaloneControlWrapper' is not defined no-undef
I tried using windom.SPClientPeoplePicker_InitStandaloneControlWrapper but the problem is in window "SPClientPeoplePicker_InitStandaloneControlWrapper" is giving me a different function. It would be nice if that library can be scoped inside my component
I tried calling library using import but it didnt work
import clientforms from "https://standardsSite.com/_layouts/15/clienttemplates.js";
I solve the problem I use loadjs its very handy.
loadjs(
[
"https://mysharepointsite.com/_layouts/15/clienttemplates.js",
"https://mysharepointsite.com/_layouts/15/clientforms.js",
"https://mysharepointsite.com/_layouts/15/clientpeoplepicker.js",
"https://mysharepointsite.com/_layouts/15/autofill.js"
],
"SPLibrary"
);
let self = this;
loadjs.ready("SPLibrary", function() {
self.handleSubmit(self.props.name);
});

Resources