This question has been asked however the solutions don't seem to work and I'm not sure why.
I have two react components that have been compiled and preprocessed to JS files. I reference each file within a script tag within my existing HTML document.
Only 1 component loads. Both work independently. It will only render/load the first script tag.
How do I get both components to render?
Path: index.html
<html>
<head> </head>
<body>
<div id="like_button_container"></div>
<br /><br /><br />
<div id="progress_bar"></div>
<script
src="https://unpkg.com/react#17/umd/react.development.js"
crossorigin
></script>
<script
src="https://unpkg.com/react-dom#17/umd/react-dom.development.js"
crossorigin
></script>
</body>
<!-- Load our React component. -->
<script src="progress_bar.js"></script>
<script src="like_button.js"></script>
</html>
Path: Progressbar.js (this is preprocessed to a JS file)
class ProgressBar extends React.Component {
constructor(props) {
super(props);
this;
}
render() {
return <div>Hello, this is a component</div>;
}
}
const domContainer = document.getElementById("progress_bar");
ReactDOM.render(<ProgressBar />, domContainer);
Path: like_button.js
"use strict";
const e = React.createElement;
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = { liked: false };
}
render() {
if (this.state.liked) {
return "You liked this.";
}
return e(
"button",
{ onClick: () => this.setState({ liked: true }) },
"Like"
);
}
}
const domContainer = document.getElementById("like_button_container");
ReactDOM.render(e(LikeButton), domContainer);
Related
I have a form to add a category. I expect that when clicking on the add button, there is a notification showing in the corner screen if the input is empty. My idea is returning a Çomponent( or function) contains a toast in handleAddNewCategory() but it's not showing. I know that the library react-bootstrap can do showing toast like this
handleAddNewCategory(){
if(condition)
return toastr.info("message",...);
}
but I don't want to use it for now. Can anyone give me a solution to solve this with using only bootstrap. I'm totally new to Reactjs.
This is some minimal file:
import React, { Component } from "react";
import AddNewCategory from "./AddNewCategory";
import Notification from "./Notification";
class CategoryList extends Component {
constructor(props) {
super(props);
this.state = {
categoryNameInput: "",
categoryDescriptionInput: "",
};
}
...
handleAddNewCategory = () => {
const { categoryNameInput, categoryDescriptionInput } = this.state;
if (categoryNameInput.trim() === "") {
return <Notification message="Please enter category name" />;
}
if (categoryDescriptionInput.trim() === "") {
return <Notification message="Please enter category description" />;
}
};
render() {
return (
<div className="container">
...
<AddNewCategory handleAddNewCategory={this.handleAddNewCategory} />
...
</div>
);
}
}
export default CategoryList;
Notification component
import React, { Component } from "react";
class Notification extends Component {
render() {
const myStyle = {
zIndex: "1001",
position: "absolute",
top: "10px",
right: "10px",
};
return (
<div className="toast col-2" style={myStyle} data-autohide="false">
<div className="toast-header">
<strong className="mr-auto text-primary">Notice</strong>
</div>
<div className="toast-body">{this.props.message}</div>
</div>
);
}
}
export default Notification;
index.html
<!DOCTYPE html>
<html lang="en">
<head>
...
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script>
$(document).ready(function() {
$('.toast').toast('show');
});
</script>
</body>
</html>
don't use jquery to show the toast it's not the best practice and instead of conditionally rendering the component what you can do is. just render it ones and then controlled its visibility.
follow the below code:-
Notification component
import React, { Component } from "react";
class Notification extends Component {
render() {
const myStyle = {
zIndex: "1001",
position: "absolute",
top: "10px",
right: "10px",
};
return (
<div hidden={this.props.showToast} className="toast col-2" style={myStyle} data-autohide="false">
<div className="toast-header">
<strong className="mr-auto text-primary">Notice</strong>
</div>
<div className="toast-body">{this.props.message}</div>
</div>
);
}
}
export default Notification;
Notification component usage :-
class CategoryList extends Component {
constructor(props) {
super(props);
this.state = {
categoryNameInput: "",
categoryDescriptionInput: "",
toastMessage:'',
showToast:false
};
}
...
handleAddNewCategory = () => {
const { categoryNameInput, categoryDescriptionInput } = this.state;
if (categoryNameInput.trim() === "") {
this.setState({
toastMessage:'Please enter category name',
showToast:true
})
}
if (categoryDescriptionInput.trim() === "") {
this.setState({
toastMessage:'Please enter category name',
showToast:true
})
}
};
render() {
return (
<div className="container">
<Notification message={this.state.toastMessage} showToast={this.state.showToast}/>;
...
<AddNewCategory handleAddNewCategory={this.handleAddNewCategory} />
...
</div>
);
}
}
export default CategoryList;
here what i do is i initialise the boolean in state and enable it so that toast will be visible and i pass it directly throw props so that whenever your message and boolean changes it automatically reflects in your notification controller.
and to remove the toast just set {showToast} to false whenever you want. and remove the jquery part from your code
i am facing issue with using react create portal.
the modal component is not shown on top of parent.
i have two roots in index.html, one is "Modal" and another is "root".
created portal on in Modal is not shown on top of the "root" tree.
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel="stylesheet" type="text/css" href="./style.css" />
</head>
<body>
<div id="modal"></div>
<div id="root"></div>
<script src="App.js"></script>
</body>
</html>
App.js:
import React from "react"
import ReactDOM from "react-dom"
import Modal from "./Modal"
class App extends React.Component
{
constructor(){
super();
this.inputNode = React.createRef();
this.submitHandler = this.submitHandler.bind(this)
}
submitHandler(){
console.log("onclided")
this.inputNode.current.focus();
event.preventDefault();
}
render(){
return(
<div>
<span
onClick={this.submitHandler}>Name</span>
<input
ref={this.inputNode}
>
</input>
<Modal/>
</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById("root"))
Modal.js:
import React from "react"
import ReactDOM from "react-dom"
const modalRoot = document.getElementById('modal');
class Modal extends React.Component {
constructor(props) {
super(props);
this.el = document.createElement('div');
}
componentDidMount() {
modalRoot.appendChild(this.el);
}
componentWillUnmount() {
modalRoot.removeChild(this.el);
}
render() {
return ReactDOM.createPortal(
<div>hello modal</div>,
this.el,
);
}
}
export default Modal;
can someone tell me what i am doing wrong here ?
in your app.js
import React from "react"
import ReactDOM from "react-dom"
import Modal from "./Modal"
const mainContainer = document.getElementById('root');
const portalContainer = document.getElementById('modal');
class App extends React.Component
{
constructor(){
super();
this.inputNode = React.createRef();
this.submitHandler = this.submitHandler.bind(this);
this.el = document.createElement('div');
}
componentDidMount() {
portalContainer.appendChild(this.el);
}
componentWillUnmount() {
portalContainer.removeChild(this.el);
}
submitHandler(){
console.log("onclided")
this.inputNode.current.focus();
event.preventDefault();
}
render(){
return(
<div>
<span
onClick={this.submitHandler}>Name</span>
<input
ref={this.inputNode}
>
</input>
{ReactDOM.createPortal(
<Modal />,
portalContainer,
);}
</div>
)
}
}
ReactDOM.render(<App/>, mainContainer)
in your Modal.js
import React from "react"
import ReactDOM from "react-dom"
class Modal extends React.Component {
render() {
<div>hello modal</div>
}
}
export default Modal;
I found the out the issue. i didn't provide style position to "Modal" div as : fixed/absolute ,so by default it took static. and both "root" and "modal" are shown up and down.
nothing wrong with my code.
I am using the code below to create a react component.
function Button(props) {
return (
<button onClick={props.handleClick}>
{props.name}
</button>
)
}
class LikeButton extends React.Component {
handleClick = () => {
console.log('ciao');
}
render() {
return (
<Button handleClick={this.handleClick}
name='Get' />
)
}
}
ReactDOM.render(<LikeButton />, document.getElementById('buttons'));
I tried the code with sandbox and it works perfectly. The problem is when I run my code, I get an error syntax in the third line of my Button function.
At first, I thought it was an error related to babel but I am using the CDN and it is supposed to work.
If you are using Babel from a CDN for experimentation you need to make sure your script tag has the attribute type="text/babel" as well.
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<script src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div id="buttons"></div>
<script type="text/babel">
function Button(props) {
return <button onClick={props.handleClick}>{props.name}</button>;
}
class LikeButton extends React.Component {
handleClick = () => {
console.log('ciao');
}
render() {
return <Button handleClick={this.handleClick} name='Get' />;
}
}
ReactDOM.render(<LikeButton />, document.getElementById('buttons'));
</script>
I'm new in reactJS, and I am trying to use pure flatpickr (https://flatpickr.js.org , NOT react-flatpickr)
Below is my current code. Any help on how to implement it properly?
import React, { Component } from "react"
import flatpickr from "flatpickr"
export default class Datepicker extends Component<IProps> {
public render() {
flatpickr(".datepicker")
return (
<div>
<input type="text" className="datepicker" />
</div>
)
}
}
flatpickr requires a node or selector passed into it. In React, for referring to the DOM, we use a ref
For handling events and providing other options, you can use the second argument for options.
Here is a demo:
class App extends React.Component {
constructor(props) {
super(props);
this.datePicker = React.createRef();
}
onChange(selectedDates, dateStr, instance) {
console.log(selectedDates);
}
componentDidMount() {
flatpickr(this.datePicker.current, {
onChange: this.onChange
});
}
render() {
return(
<input type="date" ref={this.datePicker} />
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<div id="root"></div>
Example with hooks & Typescript (I had to use useCallback and useRef to make it work):
// Or configure the styling elsewhere.
import 'flatpickr/dist/flatpickr.css';
import flatpickr from 'flatpickr';
import { Instance } from 'flatpickr/dist/types/instance';
export default function Comp() {
const fp1 = useRef() as MutableRefObject<Instance>;
const inputRef = useCallback((node) => {
if (node !== null) {
fp1.current = flatpickr(node, {});
}
}, []);
return (<input type="date" ref={inputRef} />);
}
I'm using a CMS to build interfaces and need React JS to integrate into the system via CDN links. It gives me an error when trying to load some components. Do I have to explicitly keep loading components or is there some other way? Im using the following links:
`
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="react-container"></div>
<script type="text/babel">
class Note extends React.Component {
constructor(props) {
super(props)
this.state = {
checked: true,
activePage: 1
}
this.handleCheck = this.handleCheck.bind(this)
}
handleCheck() {
this.setState({
checked: !this.state.checked
})
}
handlePageChange(pageNumber) {
this.setState({activePage: pageNumber});
}
render() {
var msg
if(this.state.checked) {
msg = "checked"
} else {
msg = "not checked"
}
return (
<div>
<input type="checkbox"
onChange={this.handleCheck}
defaultChecked={this.state.checked}/>
<Pagination
hideNavigation
activePage={this.state.activePage}
itemsCountPerPage={10}
totalItemsCount={450}
pageRangeDisplayed={10}
onChange={this.handlePageChange}
/>
</div>
)
}
}
ReactDOM.render(
<Note />,
document.getElementById('react-container')
)
</script>
`
Also, sometimes it gives me out of memory error.
Browser hangs.
Below is an example of how to use cdn for reactjs. Hope it helps :)
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<script type="text/babel">
class Greeting extends React.Component {
render() {
const name = 'Johnson';
return (<p>Hello world {name}</p>);
}
}
ReactDOM.render(
<Greeting />,
document.getElementById('root')
);
</script>