Meteorjs + React, how to render several elements in Meteor.startup - javascript

I am trying to declare two different React elements that I would like to render. The both elements are separated elements such as displayed elements (App.jsx) and the customized account system (Login.jsx). But in my test I have the same code in the both jsx file to ensure that the issue is not related to a specific part of them.
I have also created an /imports/startup/client/index.js file (called in the /client/main.js file):
import React from 'react';
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';
import './accounts-config.js';
import App from '/imports/ui/App.jsx';
import Login from '/imports/ui/Login.jsx';
Meteor.startup(() => {
render(<App />, document.getElementById('app'));
render(<Login />, document.getElementById('login'));
})
and the /client/main.html contains the related div tags:
...
<div id="app"></div>
<div id="login"></div>
...
The issue is that the second render is never displayed (here, the div login) and I observe that only the first render is interpreted.
All the examples that I've found only deals with a single react element. So I wonder how to use several separated react elements like it is in my html file ?
I am newbie in the meteorjs and react world , so maybe I didn't get the right philosophy...

You can make use of React 16 new feature that is portal.
For how to use ReactDOM.createPortal please refer to following link:
How to use ReactDOM.createPortal() in React 16?

I have solved my issue using only one render in the Meteor.startup(() (in my index.js).
The React doc specifies that only one render can be declared in the Meteor.startup(() (in my index.js).
https://reactjs.org/docs/components-and-props.html
My code is the following:
in my index.js
Meteor.startup(() => {
render(<App />, document.getElementById('app'));
})
The trick is that this Super component (App.jsx) has to be used to call all the other components. In my example by calling the Login component:
render() {
return (
<div className="container">
<Login />
</div>
)
}

I believe because the render() statement has an implicit return statement as well, so since it can only execute and return one, the next render statement isn't executed.

Related

Invalid Hook Call use-neo4j

I recently started building a react app.
I wanted to configure a neo4j database attached to the application. I decided to use the use-neo4j hook. I followed the basic step of creating the driver instance like this:
import React from "react";
import ReactDOM from "react-dom";
import "./css/index.css";
import App from "./js/App";
import Nav from "./js/Nav";
import { Neo4jProvider, createDriver } from "use-neo4j";
const driver = createDriver("neo4j", "localhost", 7687, "lode", "neo4j");
ReactDOM.render(
<React.StrictMode>
<Neo4jProvider driver={driver}>
<Nav />
<App />
</Neo4jProvider>
</React.StrictMode>,
document.getElementById("root")
);
But I ended up having the Invalid Hook Call error.
Except if I remove the Neo4jProvider tags
Seen in this image here
I tried everything I can to fix it, I'm pretty new at React.
I would love someone to help me if they can.
Just like the error says, you can only call hooks inside the body of a functional component. So I would probably create a component that initiates the driver and returns the component that uses it -
import { Neo4jProvider, createDriver } from "use-neo4j";
const NeoProvider = ({ children }) => {
const driver = createDriver("neo4j", "localhost", 7687, "lode", "neo4j");
return (
<Neo4jProvider driver={driver}>
{children}
</Neo4jProvider>
);
}
And then import that at your top level and use that instead of the Neo4jProvider you're importing from the package.
Fixed the issue, I had multiple Reactjs running

Instance of a functional component is said to be unrecognized in browser. Why is that?

I am using a JSON format text file to import items from there to another js file using react. I am using the map method in JS to iterate through the item in the JSON file. However an error keeps popping up that my functional component is unrecognized.
import React from "react"
import products from "./vschoolProducts"
import product from "./product"
function App() {
const listofp = products.map(function(pro){
return <product key={pro.id} product= {pro} />
})
return (
<div>
{listofp}
</div>
)
}
export default App
Any ideas of why it is unrecognized ?
It's silly of me, but the error can be resolved simply by making the first letter of the react component in upper caps.
The product component in product.js needs to be changed to Product.
Subsequently every instance of product must be changed to Product.
Functional components must always start with Caps.

React class not rendering

I'm trying to follow along with the reactjs tic tac toe tutorial, but when I try to render the pages and I have this code
import React from 'react'
import ReactDOM from 'react-dom'
import Game from '../components/Game'
document.addEventListener('DOMContentLoaded', () => {
ReactDOM.render(
console.log("render is working"),
<Game />,
document.getElementById('root'),
);
})
and the Game class looks like
import React from 'react'
import ReactDOM from 'react-dom'
import Board from './Board'
class Game extends React.Component {
render() {
console.log("Hooray, the game is working")
return (
<div className="game">
<div className="game-board">
<Board />
</div>
<div className="game-info">
<div>{/* status */}</div>
<ol>{/* TODO */}</ol>
</div>
</div>
);
}
}
export default Game
The 'render is working prints to the console but the console log that says "Hooray, the game is working" doesn't show up, so it seems like the
Game class isn't getting rendered for some reason. I'm using ruby on rails with the built in webpacker to load all the javascripts
Cause calling console.log evaluates to undefined you are basically doing:
ReactDOM.render(
undefined, // <- react component
<Game />, // <- target
document.getElementById('root'), // < - useless
);
I'm surprised that ReactDOM.render is not throwing an error although you are passing completely useless arguments to it.
ReactDOM.render() takes 2 arguments: component, and mounting DOM element. You are passing a console.log for the first argument.
For one, why do you have your ReactDom.render(...) wrapped in that event listener?
Two, why are you passing the ReactDom.render(...) a console.log()? It should only take two arguments: a component, and the element it should be appended to. Try removing the console.log() and if that still doesn't work, try removing the event listener that wraps your ReactDoom.render(...).
You need to remove the console log from the ReactDOM render call.
If I need to render in a component, I can do it as such.
<div>
.....
{console.log('Inline console in render method')}
</div>
Your render should be as follows:
ReactDOM.render(<Game />, document.getElementById('root);
Assuming your child component is passed as 'export default Game' and your Id of your HTML base file is 'root'.
Render only takes two arguments. The first being the component being passed in and the second is the target in which it should place itself. You should only need to do this step at your 'index.js' file. Nowhere else.

React Components - Where to store HTML Templates

Complete newbie to React and trying to find out how to load the HTML for components rather than inserting it directly in the render method. For example
import React, {Component} from 'react';
export default class Login extends Component {
render() {
return (
<!-- how can I provide a link to the HTML template for here? -->
);
}
}
React does not have HTML. The JSX that you write in the render method is actually compiled into JavaScript. At the core, React components are all JavaScript. The styles are also inline. Componentisation is neat in React because HTML, CSS, JavaScript (interactions) are all in one place, as JavaScript.
To insert raw HTML, React has an attribute dangerouslySetInnerHTML.
<div dangerouslySetInnerHTML={createMarkup()} />
If you want some type of organization, you can use variables to set the html and then assign that to the render functionalty, but React does not use html templates
var hello = React.createClass({
render: yourVariable
});
I think you might be confused about how JSX works.Just in case, I want to clarify that JSX is what they call "syntactic sugar", that turns React methods such as React.createElement into that XML like syntax. For instance:
var Nav;
// Input (JSX):
var app = <Nav color="blue" />;
// Output (JS):
var app = React.createElement(Nav, {color:"blue"});
(from the React docs)
So, to the best of my knowledge, the JSX syntax actually belongs in the render method. If what you are really looking for is the best way to separate and reuse purely presentational code, you should read on separating your app into Container and Presentational components
https://medium.com/#learnreact/container-components-c0e67432e005#.dzjqc8yrn
https://medium.com/#dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.mn9nf6lz6
Stateless/Presentational/Dumb Components are just functions that return JSX. So you could have your Template component:
import React from 'react';
//you need to import React to use JSX, as it will be expanded into React.createElement calls...
function Template(props){
return (
//...your template here...
);
}
And then your class
import React, {Component} from 'react';
export default class Login extends Component {
render() {
return (<Template {...props}/>);
}
}
}
Makes sense?

React.js renderDOM conditionally

I'm new to React. I have some issue on render with reactDom:
index.js
import ReactDOM from 'react-dom';
import A from 'components/A';
import B from 'components/B';
render(<A />, document.getElementById('A'));
render(<B />, document.getElementById('B'));
I want to show something like
render A to page A
render B to page B
The problem is when I define A and B together on index.js, so on page A (not have elementId B here), it will show error like below because React doesn't have elementId B on page A
Invalid Violation Register Component Target container is not a DOM element
Checking by path like React and Browserify Register Component Error can fix it too, or checking elementid(exists or not) before calling render.
I'd like to know if this is the right way to solve case like this, or is there another way?
Try something like this:
if (document.getElementById('A')) {
render(<A />, document.getElementById('A'));
}
if (document.getElementById('B')) {
render(<B />, document.getElementById('B'));
}
This is the simplest and easiest solution to your problem (it's not the cleanest nor the best solution but it is easiest to understand when learning React and how it works with the DOM). It will not render <A /> if it cannot find A container, and it will not render <B /> if it cannot find B container.

Categories