Confusion with default import of React - javascript

To import React we write import React from 'react'.
But this is a default export right ? So if I change its name to something else other than React it should also work. But it doesn't work. Can anyone please explain why?

Essentially, JSX compilers (like Babel/TypeScript) convert the JSX code to pure JavaScript.
For example, the following JSX code:
const Element = () => (
<div>
Hey there
</div>
);
is compiled into:
const Element = () => (
React.createElement("div", null, "Hey there")
);
Which is now valid JavaScript that can be parsed by the browser.
As you may have noticed, it uses the React.createElement function to create the div. This is why changing the name of the import doesn't work - the compiler still tries to use React.
Babel lets you configure this using the pragma option, if desired, allowing you to use a different function name.
TypeScript can do the same using the jsxFactory compiler option.

It works so, as you use Babel, or something similar, to translate JSX.
So when you input something like this:
function AComponent() {
return <div>Hello world</div>
}
You will get the next transpiled code:
"use strict";
function AComponent() {
return React.createElement("div", null, "Hello world");
}
By this reason you should use the definite name of React.
You can try it here: https://babeljs.io/repl#?babili=false&browsers=&build=&builtIns=false&spec=false&loose=false&code_lz=AQ4MwVwOwYwFwJYHsrAIIGEkFsAOKBTKOACgEpgBvAKFBACcC4J7UAeAEwQDcA-ACQIAbIUmAB3JPSEc2Aei59aoAL5A&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=es2015%2Creact%2Cstage-2&prettier=false&targets=&version=7.4.4&externalPlugins=

Related

JSX without react. Just pure es6 and HTML

Good day fellow devs! Is it possible to return a jsx format from a function without using react? My project is just pure Es6 and HTML. Here's what I want to do, I want to create a separate files for functions and HTML then call the HTML format files in the functions.
For example, here's my main.js:
import renderHTML from './display/render.js';
import createElement from './functions/createElement.js';
var popup = document.getElementById('popup-container');
const HTML = `${renderHTML}`;
const Fragment = createElement(HTML);
popup.appendChild(Fragment);
Then in my renderHTML file where it's jsx format, here's the content:
export default function renderHTML() {
return (
<h1>I am the content! Rendered successfully!</h1>
)
}
There, hope that made sense lol.. But yeah, the output of that is either its code or object. Any help or advice if I'm doing it wrong is much appreciated. Thank you so much and have a nice day ahead!

Appending JSX in React Native

I'm searching for a way to add a JSX element programmatically in React Native. Not conditionally.
It needs to be independent function, so far I couldn't find anything about this. Let me give you code example;
const appendJSX = () => {
const jsx = <Text> Hello! </Text>
append(jsx) // <---- can we do something like this?
}
let's say I call this function with useEffect and it should add whatever jsx I have inside the function. Up until this point I always see things like pushing inside of an array or something like that.
UPDATE
Equivalent behaviour that works on web;
useEffect(() => {
const div = document.createElement("div");
div.innerText = "appended div"
document.body.append(div)
}, [])
As you can see we don't have to touch any JSX in application. Reaching document.body and appending whatever we want is possible in React Web. But how can we achieve this in React Native?
Not quite sure what you want to do, but as for to add a JSX manually. Here's the answer.
JSX is already part of the language in most of the cases.
const a = <Text />
export default a
Will translates into:
const a = createElement(Text, null, null)
export default a
Therefore in most of common cases, if you continue using React somewhere else, then the variable a holds a React element without any compilation error.
You might wonder what a actually really holds, it's an object:
const a = {
$$typeof: Symbol(ReactElement),
props: null,
type: Text
}
So you can see the only dependencies in above piece is Text and the ReactElement Symbol. As long as you can resolve them, you are good to export this to anywhere. The latter is normally taken care by Babel.
NOTE:
There's a difference between Text and <Text />. If you just want to export a Text which is a function component, there'll tutorial online, also you can dig into any third party library, because essentially that's what they do, export Text so other people can use it.

REACT: Call an external js function in a react component [duplicate]

This question already has answers here:
When should I use curly braces for ES6 import?
(11 answers)
How to export & import custom helpers in JS/React?
(2 answers)
Closed 1 year ago.
Anyone know in reactjs how to be able to call that 'openSideMenu' function which is in the vanilla js file that I imported on the top?
You can't.
The function will be scoped to the module and inaccessible outside it.
Rewrite the module you are importing so it exports the data you need.
A dirty hack would be to:
Load the JS file using a <script> element
Ensure that it sets the function as a global
Access window.thatfunction inside the React app
but that's fiddley and has the usual problems of globals.
To further what Quentin said, you're not doing react in a react-y way. To be clear, it's always going to be harder and more confusing to do stuff the wrong way when dealing with react.
The react way to do what you want is something like this:
function NavBarLogo({onLogoClick}) {
return (
<nav>
<img ... onClick={onLogoClick}/>
<img ... />
</nav>
)
}
Whatever renders NavBarLogo looks something like this:
function NavBarContainer() {
cons [className,setClassName] = React.useState('closed');
const handleLogoClick = () => setClassName(c => c === 'closed' ? 'opened' : 'closed')
return (
<div className={className}>
<NavBarLogo onLogoClick={handleLogoClick}>
... other stuff
</div>
)
}
If you exported your openSideMenu function in your sideMenuFunction.js file as default, then you need to import like this:
import openSideMenu from '../../utils/sideMenuFunction';
if not as default, then you need to import like this:
import { openSideMenu } from '../../utils/sideMenuFunction';
Make sure the names are the same both where you import and from where you import and it will work fine.
When you want to call an external function, you have to export it from the file it's contained in.
So in your example, you would want to have:
import { openSideMenu } from '../../utils/functions.js';
and then in 'functions.js' you would have:
export const openSideMenu = () => {
// Do Stuff Here...
}
And then you'll have no problem calling 'openSideMenu' from your onClick just how you have it

render React component from a string

I have some React code in the string, for example:
const component = `
function App() {
return (
<div>
test
</div>
);
}
`;
And I want to be able to render that component from within browser, something like:
import React, { Component } from 'react';
import { render } from 'react-dom';
import * as babel from 'babel-standalone';
const babelCode = babel.transform(component, { presets: ['react', 'es2015'] }).code;
render(eval(babelCode), document.getElementById('WorkFlow'));
This particular example doesn't work but it shows what I'm looking for, any help appreciated!
Thanks!
Babel produces the code with "use strict" and eval() doesn't work with it well. First, we should remove that line manually.
const code = babelCode.replace('"use strict";', "").trim();
Ideally, after this following lines should work.
eval(code);
render(<App/>, document.getElementById('WorkFlow'));
Note that you don't need to put eval() inside render. It doesn't return your App function or anything. Instead, it will add App to context and we can use it after eval() statement.
But usually, React app has a compile step with webpack or similar tool and will complain about undefined App.
As a workaround, we can wrap our component with a Function which returns our component itself. Now we can call this function to get our component. But the context of wrapping function doesn't have React variable. So we have to pass it manually as a parameter. If you are going to use any other variable from the current context, you will have to pass those as well.
const code = babelCode.replace('"use strict";', "").trim();
const func = new Function("React", `return ${code}`);
const App = func(React)
render(<App/>, document.getElementById('WorkFlow'));
Hope this helps!
React will allow you to render either a Component or an Element. You can think of an Element as a raw HTML code in JSX, while a Component is a prototype, which inherits from React.Component. In your code you are trying to render a result of evaluating the babel transpiled code, which will fail (I'm not sure what it is, but it's probably undefined or null). If you want to make it work, first evaluate the code and then invoke the function to pass the Element code to the render function:
eval(babelCode); // now the App function has been defined and you can use it in the code
render(App(), document.getElementById('WorkFlow'));
// ^^ here the App function is being invoked
Old answer (I thought you were trying to pass the component as a file not and not as a variable to transpiler):
babel will never transpile strings, so this is not going to work out for you. You can however consider using a raw JS code instead of JSX as your string content. More about it you can read here: https://facebook.github.io/react/docs/react-without-jsx.html

How does render work in ReactJS with those HTML tags being "returned"

In React code I see return (<form> .. </form>); with HTML inside... is this valid Javascript? Is it somehow converted to a string or something?
I am learning Javascript right now and certainly have some gaps. This puzzles me how this is done though!
var AddTodoComponent = React.createClass({
render: function () {
return (
<form>
<input type="text" disabled={AppStore.isSaving()}/>
</form>
);
}
});
This syntax is called JSX. It is not normally valid JavaScript in the sense that your browser will probably not pick it up, but with a transpiler you can achieve proper JavaScript.
In the link above, you'll also see how to write valid JavaScript right off the bat, avoiding the JSX syntax.(which is what the transpiler would produce).
The following sample is from Facebook's JSX in Depth guide linked above
var Nav, Profile;
// Input (JSX):
var app = <Nav color="blue"><Profile>click</Profile></Nav>;
// Output (JS):
var app = React.createElement(
Nav,
{color:"blue"},
React.createElement(Profile, null, "click")
);
As you can see, in the output section, React defines a method which performs the render for you, React.createElement

Categories

Resources