Problem with loading images from a javascript file in react - javascript

I have a problem using "setInterval" within React. If I don't use "setInterval", there's no problem, but when I use it, my images won't appeear on my page.Please help.
Here is my component where I've imported the JS file containing the images:
import React from 'react';
import ReactDOM from 'react-dom';
import logo from './lastricouri.jpg';
import img from './app.js';
import inter from './app.js';
class Logo extends React.Component {
render() {
return (
<div id = 'header-container'>
<img src ={logo} id='tricouri'></img>
<img src={inter}></img>
<div id='btns'>
<a href='#' id='logi'>Log In</a>
<a href='#' id='signup'>Sign Up</a>
</div>
<input type='text' id='txt' placeholder='Ai libertatea de a alege!'></input>
</div>
);
}
}
export default Logo;
And here is my component that contains the images:
import first from './1.jpg';
import second from './2.jpg';
import third from './3.jpg';
import fourth from './4.jpg';
import fifth from './5.jpg';
let inter = setInterval(() => {
const tshirts = [first,second,third,fourth,fifth];
const rndimg = Math.floor(Math.random() * 5);
const img = tshirts[rndimg];
},3000);
export default inter;

SetInterval returns a unique interval id which is being assigned to the inter variable. inter does not contain your image source. If you want to assign a random image change your code like this
let inter;
setInterval(() => {
const tshirts = [first,second,third,fourth,fifth];
const rndimg = Math.floor(Math.random() * 5);
inter = tshirts[rndimg];
},3000);
export default inter;

Related

onclick function is not working inside script tag

<section id="main">
<button class='btn' onclick="deleteNote()" type="button">Delete</button>
</section>
<script type="module">
import { initializeApp } from 'https://www.gstatic.com/firebasejs/9.6.11/firebase-app.js'
import {
getDatabase, ref, child, get, onValue, onChildAdded, onChildChanged, onChildRemoved,push,set,remove
} from 'https://www.gstatic.com/firebasejs/9.6.11/firebase-database.js';
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const db = getDatabase();
function deleteNote(){
// console.log(key);
console.log('deleting');
}
Why the onclick is not working? But when I define the function inside different script tag it works.
Inside the Script tag, you have to call the function to execute it
function deleteNote(){
// console.log(key);
console.log('deleting');
}
deleteNote();
And if you are using it on any HTML page don't forget to import the script or use the script on the same page and check your browsers support the module value read more

Can insert React JSX <Link> with innerHTML method?

I have some html (JSX) in my react app that looks like this:
<div><h3>Title</h3><p> some message...</p></div>
I am then assigning this to a variable called msg using innerHTML like so:
let msg
msg.innerHTML = "<div><h3>Title</h3><p> some message...</p></div>"
//then i append it to my app like this
document.body.appendChild(msg)
Now i would like to surround the html above with a native React Link element like so
msg.innerHTML = "<Link to"/"><div><h3>Title</h3><p> some message...</p></div></Link>"
of course it doesn't work and it is compiled as regular html when it is rendered to the page as and doesn't act as a react link
How can i achieve this, is it even possible or is there a totally different way of approaching this issue?
I tried doing this and many different variations but to no cigar:
msg.innerHTML = `${<Link to"/">}<div><h3>Title</h3><p> some message...</p></div>${</Link}`
There is ReactDOMServer.renderToString that will render a React element to its initial HTML.
...
import ReactDOMServer from "react-dom/server";
export default function App() {
useEffect(() => {
const msg = document.createElement("div");
msg.innerHTML = ReactDOMServer.renderToString(
<Link to="/">
<div>
<h3>Title</h3>
<p> some message...</p>
</div>
</Link>
);
document.body.appendChild(msg);
}, []);
return null;
}

Switch between two external css files in react

I want to apply an option where user can switch between dark mode and light mode in the application.
<link rel="stylesheet" href="../src/cssf/light.css">
<link rel="stylesheet" href="../src/cssf/dark.css">
I have two sheets for the whole website.
<label class="form-check-label" id="dark">
<input type="radio" class="form-check-input" checked name="theme"><label>Dark</label>
</label>
</div>
<div class="form-check-inline">
<label class="form-check-label" id="light">
<input type="radio" class="form-check-input" name="theme"><label>Light</label>
</label>
I have given the option but what do i have to do to switch between the two css files?
import React, { useEffect, useState } from "react";
import "./cssf/style.css";
import logo from "./cssf/logo-sm.png";
function App() {
const [ stylePath, setStylePath ] = useState("./cssf/dark-theme.css");
const handleButtonClick = () => {
setStylePath("./cssf/light-theme.css");
}
useEffect(() => {
var head = document.head;
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = stylePath;
head.appendChild(link);
return () => { head.removeChild(link); }
}, [stylePath]);
I used this method and it is updating the link tag perfectly in the head but without importing it to my app using import "../cssf/sheername.css" it is of no use.How can i solve it?
that’s quite an interesting issue.
For dynamically importing css files into react I’d check this thread: here
However I don’t think this is the best solution, as it is potentially very hard to maintain and not very DRY.
I would rather have 1 css file that looks at the class on body and changes css colors based on that (assuming you don’t change layout, only colors)

How do I convert html with jsx to jsx in React.js

I want to have an API with returns HTML with JSX. When the HTML is loaded, I want to convert this to JSX and pass the props from my
Given this set of code:
import { renderToString } from "react-dom/server";
import ReactDOM from 'react-dom';
function MyHtml (props) {
var apiHtml = renderToString("<div>{this.props.title}</div>");
return (
<div dangerouslySetInnerHTML={{ __html: apiHtml }} />
)
}
export default MyHtml;
ReactDOM.render(
<MyHtml title="test"/>,
document.getElementById('test')
);
I want to have the output
<div>test</div>
Instead, I get
<div>{this.props.title}</div>
Thanks
I think what you're looking for is:
var apiHtml = renderToString(`<div>{${this.props.title}}</div>`);
Using template literals to fill in the code you want.
I ended up doing something like this:
var { title } = this.props; // => testing
var html = ReactDOMServer.renderToString("<div>${title}</div>");
var toRender = eval('`'+html +'`');
To give the output:
<div>testing</div>
Thanks everyone!

React: Script tag not working when inserted using dangerouslySetInnerHTML

I'm trying to set html sent from my server to show inside a div using dangerouslySetInnerHTML property in React. I also have script tag inside it and use functions defined in same inside that html. I have made example of error in JSFiddle here.
This is test code:
var x = '<html><scr'+'ipt>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</scr'+'ipt><body><p onClick="pClicked()">Hello</p></body></html>';
var Hello = React.createClass({
displayName: 'Hello',
render: function() {
return (<div dangerouslySetInnerHTML={{__html: x}} />);
}
});
I checked and the script tag is added to DOM, but cannot call the functions defined within that script tag. If this is not the correct way is there any other way by which I can inject the script tag's content.
I created a React component that works pretty much like dangerouslySetInnerHtml but additionally it executes all the js code that it finds on the html string, check it out, it might help you:
https://www.npmjs.com/package/dangerously-set-html-content
Here's a bit of a dirty way of getting it done ,
A bit of an explanation as to whats happening here , you extract the script contents via a regex , and only render html using react , then after the component is mounted the content in script tag is run on a global scope.
var x = '<html><scr'+'ipt>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</scr'+'ipt><body><p onClick="pClicked()">Hello</p></body></html>';
var extractscript=/<script>(.+)<\/script>/gi.exec(x);
x=x.replace(extractscript[0],"");
var Hello = React.createClass({
displayName: 'Hello',
componentDidMount: function() {
// this runs the contents in script tag on a window/global scope
window.eval(extractscript[1]);
},
render: function() {
return (<div dangerouslySetInnerHTML={{__html: x}} />);
}
});
ReactDOM.render(
React.createElement(Hello),
document.getElementById('container')
);
I don't think you need to use concatenation (+) here.
var x = '<html><scr'+'ipt>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</scr'+'ipt><body><p onClick="pClicked()">Hello</p></body></html>';
I think you can just do:
var x = '<html><script>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</script><body><p onClick="pClicked()">Hello</p></body></html>';
Since it's passed to dangerouslySetInnerHTML anyway.
But let's get back to the issue. You don't need to use regex to access the script tag's content. If you add id attribute, for example <script id="myId">...</script>, you can easily access the element.
Let's see an example of such implementation.
const x = `
<html>
<script id="myScript">
alert("this.is.sparta");
function pClicked() {console.log("p is clicked");}
</script>
<body>
<p onClick="pClicked()">Hello</p>
</body>
</html>
`;
const Hello = React.createClass({
displayName: 'Hello',
componentDidMount() {
const script = document.getElementById('myScript').innerHTML;
window.eval(script);
}
render() {
return <div dangerouslySetInnerHTML={{__html: x}} />;
}
});
If you have multiple scripts, you can add a data attribute [data-my-script] for example, and then access it using jQuery:
const x = `
<html>
<script data-my-script="">
alert("this.is.sparta");
function pClicked() {console.log("p is clicked");}
</script>
<script data-my-script="">
alert("another script");
</script>
<body>
<p onClick="pClicked()">Hello</p>
</body>
</html>
`;
const Hello = React.createClass({
constructor(props) {
super(props);
this.helloElement = null;
}
displayName: 'Hello',
componentDidMount() {
$(this.helloElement).find('[data-my-script]').each(function forEachScript() {
const script = $(this).text();
window.eval(script);
});
}
render() {
return (
<div
ref={helloElement => (this.helloElement = helloElement)}
dangerouslySetInnerHTML={{__html: x}}
/>
);
}
});
In any case, it's always good to avoid using eval, so another option is to get the text and append a new script tag with the original's script contents instead of calling eval. This answer suggests such approach
a little extension for Dasith's answer for future views...
I had a very similar issue but the in my case I got the HTML from the server side and it took a while (part of reporting solution where backend will render report to html)
so what I did was very similar only that I handled the script running in the componentWillMount() function:
import React from 'react';
import jsreport from 'jsreport-browser-client-dist'
import logo from './logo.svg';
import './App.css';
class App extends React.Component {
constructor() {
super()
this.state = {
report: "",
reportScript: ""
}
}
componentWillMount() {
jsreport.serverUrl = 'http://localhost:5488';
let reportRequest = {template: {shortid: 'HJH11D83ce'}}
// let temp = "this is temp"
jsreport.renderAsync(reportRequest)
.then(res => {
let htmlResponse = res.toString()
let extractedScript = /<script>[\s\S]*<\/script>/g.exec(htmlResponse)[0];
// console.log('html is: ',htmlResponse)
// console.log('script is: ',extractedScript)
this.setState({report: htmlResponse})
this.setState({reportScript: extractedScript})
})
}
render() {
let report = this.state.report
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo"/>
<h2>Welcome to React</h2>
</div>
<div id="reportPlaceholder">
<div dangerouslySetInnerHTML={{__html: report}}/>
</div>
</div>
);
}
componentDidUpdate() {
// this runs the contents in script tag on a window/global scope
let scriptToRun = this.state.reportScript
if (scriptToRun !== undefined) {
//remove <script> and </script> tags since eval expects only code without html tags
let scriptLines = scriptToRun.split("\n")
scriptLines.pop()
scriptLines.shift()
let cleanScript = scriptLines.join("\n")
console.log('running script ',cleanScript)
window.eval(cleanScript)
}
}
}
export default App;
hope this is helpful...
Just use some known XSS tricks. We just had a case where we had to inject a script and couldn't wait for the release so here goes our loader:
<img src onerror="var script = document.createElement('script');script.src = 'http:';document.body.appendChild(script);"/>

Categories

Resources