Apanding external HTML to a react component is not working - javascript

Basically I want to add an static HTML to a react component from external script.
So I'm saving the reference of this to window variable as follows:
let { PropTypes } = React;
export default class Body extends React.Component {
constructor(){
super();
let frmTrgt={};
frmTrgt.refff=this;
console.log("tthis: ",this);
window.bdyRefrence=frmTrgt;
}
static defaultProps = {
items: []
};
static propTypes = {
items: PropTypes.array.isRequired
};
render() {
return (
<div className={styles.body}>
<h1 className={styles.header}>React Seed</h1>
<p>This is an example seed app, powered by React, ES6 & webpack.</p>
<p>Here is some example data:</p>
<Menu items={this.props.items} />
<div>
<h1>Dynamic Content</h1>
<div id="myDynamicContent"></div>
</div>
</div>
);
}
}
and in my script tag in INDEX.html( Outside Script) I'm doing like following:
function addPHtml() {
try {
window.bdyRefrence.refff.refs.formTarget.insertAdjacentHTML("<p id='mhere'>paragraph 2</p>");
}catch (err){
console.log("err: ",err);
}
}
but when I'm calling addPHtml it is giving following error:
err: TypeError: Cannot read property 'insertAdjacentHTML' of undefined
at addPHtml ((index):19)
at <anonymous>:1:1

What your trying to do is not the correct way to insert the element in React, still for you requirement please refer below mentioned code
Your render function should be like
return(
<div>
<div ref="formTarget"></div>
<h1 >React Seed</h1>
<p>This is an example seed app, powered by React, ES6 & webpack.</p>
<p>Here is some example data:</p>
<div>
<h1>Dynamic Content</h1>
<div id="myDynamicContent"></div>
</div>
</div>
)
Please check Demo here Demo
In case using new React syntax (Createclass is deprecated now) use
window.refferedItem.refs.formTarget.getDOMNode().insertAdjacentHTML

Related

ReactJS rendering data that is passed from a laravel controller as json string

I'm totally new to React.
i want to retrive data from a database using laravel ;
in my controller, I receive the data and send it in json form like this
public function index()
{
$data = DB::table('posts')->get();
return view('welcome')->withData(json_encode($data));
}
and its working perfectly.
Inside my home view, i called react like this.
<div id="example" data="{{ $data }}"></div>
<script src="js/app.js" ></script>
and this is the Example.js :
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
export default class Example extends Component
{
constructor(props)
{
super(props);
console.log(props.data);//[{"id":1,"name":"Laravel","created_at":null,"updated_at":null},{"id":2,"name":"Reacts Js","created_at":null,"updated_at":null}]
const json = JSON.parse(props.data);
var L = json.length;//2
for(var i =0 ; i < L ; i++)
{
console.log(json[i].name);//i==0 : Laravel
// i==1 : Reacts Js
}
}
render()
{
return (
<div className="container">
<div className="row justify-content-center">
<div className="col-md-8">
<div className="card">
<div className="card-header">Example Component</div>
for(var i =0 ; i < L ; i++)
{
<div>{json[i].name}</div>
}
<div className="card-body">I'm an example component!</div>
</div>
</div>
</div>
</div>
);
}
}
if (document.getElementById('example')) {
var data = document.getElementById(('example')).getAttribute('data');
ReactDOM.render(<Example data={data}/>, document.getElementById('example'));
}
in the browsers console i can see json[i].name perfectly ! BUT in the component i have this problem with the followinf error : Uncaught TypeError: Cannot read property 'name' of undefined.
It is because JSON is within the scope of constructor and is not visible outside of it.
You would want to store the data in the component state and user that in render.
You can use then .map to iterate the JSON data in render().
class Example extends Component {
constructor(props) {
super(props);
console.log(props.data);//[{"id":1,"name":"Laravel","created_at":null,"updated_at":null},{"id":2,"name":"Reacts Js","created_at":null,"updated_at":null}]
this.state = {
json:JSON.parse(props.data)
};
}
render() {
return (
<div className="container">
<div className="row justify-content-center">
<div className="col-md-8">
<div className="card">
<div className="card-header">Example Component</div>
{this.state.json.map(i => (
<div>{i.name}</div>
))}
<div className="card-body">I'm an example component!</div>
</div>
</div>
</div>
</div>
);
}
}
Here is ReactJS's explanation on state

TypeError using Materialize-CSS with React

i'm having a problem using Materialize-CSS carousel.
The standard way to create the carousel is :
<div class="carousel">
<a class="carousel-item" href="#one!"><img
src="https://lorempixel.com/250/250/nature/1"></a>
<a class="carousel-item" href="#two!"><img
src="https://lorempixel.com/250/250/nature/2"></a>
<a class="carousel-item" href="#three!"><img
src="https://lorempixel.com/250/250/nature/3"></a>
</div>
But I want to create a carousel item for every item in an array named
"products" hence i'm trying this code in the JSX :
<div className="carousel">
{generalStore.products.map(p =>
<a className="carousel-item"><img src={p.pic} /></a>)}
</div>
p,pic == image url
But this returns an error :
TypeError: Cannot read property 'clientWidth' of undefined
Ant ideas to solve this?
Thanks
It can be implemented in materializeCSS also.
For this, you need to do npm install materialize-css#next. After this, you need to import the materialize-css in your component JS file.
To use the Javascript materialize-css components, a reference of these components has to be made in componentDidMount() has to be made and then it can be used in ref.
CodeSandBox - Working Demo
import React, { Component } from "react";
import M from "materialize-css";
import "materialize-css/dist/css/materialize.min.css";
import data from "./data.json";
class Carousel extends Component {
componentDidMount() {
const options = {
duration: 300,
onCycleTo: () => {
console.log("New Slide");
}
};
M.Carousel.init(this.Carousel, options);
}
renderThis = () => {
return data.map(i => (
<a key={i.url} className="carousel-item">
<img src={i.url} />
</a>
));
};
render() {
return (
<div
ref={Carousel => {
this.Carousel = Carousel;
}}
className="carousel"
>
{this.renderThis()}
</div>
);
}
}
export default Carousel;

Injecting dynamic HTML in React - CSS is not working

Fetching dynamic HTML from an API, the HTML is loading fine but the CSS is not working for this new HTML.
Do you I need to reload the CSS.
import React, { Component } from "react";
import Utility from "../common/Utility";
class Template extends Component {
constructor(props) {
super(props);
this.token = localStorage.getItem("token");
this.client_id = localStorage.getItem("client_id");
}
componentDidMount() {
//fetching dynamic html
Utility.ExecuteData("template", this.token, {
client_id: this.client_id
}).then(result => {
var dynamic_html = document.getElementById("dynamic_html");
dynamic_html.innerHTML = result.data[0].template;
});
}
render() {
return (
<React.Fragment>
<div id="dynamic_html" />
</React.Fragment>
);
}
}
export default Template;
It is possible to get this to work but instead of className you'll need to use the usual HTML class attribute. I've used dangerouslySetInnerHTML here, but it's the same result if you set the innerHTML of the element like you did in your question.
function Template({ html }) {
return (
<div dangerouslySetInnerHTML={{__html: html}} />
);
}
const html = '<div class="heading">With style</div>';
ReactDOM.render(
<Template html={html} />,
document.getElementById('container')
);
.heading {
font-size: 2em;
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container"></div>
I can't comment so I'm posting it in an answer instead.
I don't know how the html is being returned from the API but I assume the css is either inlined or included as a file in the remote HTML.
If the latter is the case, it might be a possibility that the url to the css file is relative, so calling the url from another server would result in a 404.

Fallback message for empty object meteor/react

I would like to show a message if there aren't objects to be returned. Something like: 'currently there are no customers available'.
I tried to tinker a bit with Object.getOwnPropertyNames() but could not get it working because the mapping function does not being called. I'm not sure where to put this check, inside the rendering function, in the with tracker or render call inside the template.
I use Meteor/react and my code looks like this:
import React, {Component} from 'react';
import {withTracker} from 'meteor/react-meteor-data';
import {Link} from 'react-router-dom';
class ArchiveCustomerOverview extends Component {
renderCustomerList() {
return this.props.users.map( user => {
return(
<div className="row" key={user._id}>
<Link to={}>
<span className="medium-1">{user.profile.name}</span>
<span className="medium-4">{user.profile.company}</span>
<span className="medium-3">{user.profile.phone}</span>
<span className="medium-3">{user.emails[0].address}</span>
</Link>
</div>
)
});
}
render() {
return (
<div>
<div className="list-overview">
<div className="list-wrapper">
<div className="list-box clear">
{this.renderCustomerList()}
</div>
</div>
</div>
</div>
);
}
}
export default withTracker( (props) => {
Meteor.subscribe('users');
return {
users: Meteor.users.find({
'profile.isArchived': 0,
'roles.customers' : 'customer'
}).fetch()
};
})(ArchiveCustomerOverview);
Just check on the number of users before you render them like this:
renderCustomerList() {
if (this.props.users.length === 0) {
return (<div>Currently there are no customers available</div>)
}
return this.props.users.map( user => {
But a word of warning: you may not get what you want from the users collection - for security reasons it is treated differently from other collections.

(reactjs) Include local Images in react component

I have the following component, which renders an image using html img src=".."
export default class Landing extends Component{
render() {
return(
<div className="topimg">
<img src={'test.jpg'}/>
</div>
But the Page does not display the image. The folder structure is the following
/layout/Landing.jsx
/layour/test.jpg
It works for web urls but not for local files.
Not sure how you are building your app but you could attach your images to the component by requireing them first. That way the app knows to include the image (referenced relatively from the component) before rendering.
export default class Landing extends Component {
constructor( props ) {
super(props);
this.images = {
test: require('./test.jpg')
};
}
render() {
return (
<div className="topimg">
<img src={this.images.test}/>
</div>
);
}
}

Categories