Display JSX code from a JSON data in Reactjs - json

I have a JSON which contains JSX code i.e
var data = {"content":"<ul className='list-group'><li className='list-group-item' onClick={this.svgMapClicked}>Name: Firmino</li><li className='list-group-item' >Goals: 22</li></ul>"}
In my Component, first I import the JSON i.e
import data from './data.json';
Then I have
this.state = {footy: data}
Now in my render function, I want to display it like but get the content from the JSON data:
render() {<div><ul className='list-group'><li className='list-group-item' onClick={this.svgMapClicked}>Name: Firmino</li><li className='list-group-item' >Goals: 22</li></ul></div>};
So, here is my render function:
render(){<div>{this.state.footy.content}</div>};
Instead of the JSX tag, {this.state.footy.content} is displayed as a string. I have searched for similar issue but I was unable to find.

Instead of storing the content HTML in json, you should store the data and create the content in JSX like
var data = [
{name: 'Firmino', goals: 22}
];
this.state = {footy: data}
and in render
render() {
return <div>
<ul className='list-group'>
{this.state.footy.map((player) => {
return <React.Fragment>
<li className='list-group-item' onClick={() => this.svgMapClicked(player)}>Name: {player.name}</li>
<li className='list-group-item' >Goals: {player.goals}</li>
</React.Fragment>
})}
</ul>
</div>
};
If you absolutely need to render the HTML then, you could use dangerouslySetInnerHTML like
render() {
return <div dangerouslySetInnerHTML={ { __html : this.state.footy} } />};

Related

Trying to use Typed.js in react

I am trying to use Typed.js on my website, and I have been getting many errors I cant find a way to fix them.
I have looked through GitHub, and I have found the exact same problem that someone had I used that code in my document and the errors are still popping up. The errors are always Expression Expected and } expected also, Unexpected token. Did you mean {'}? Here is a picture of the errors too. Here is the errors that are resulting:
errors
import "./App.css";
import Typed from "typed.js";
import { useEffect, useRef } from "react";
function HomePage() {
return (
<>
<body>
<div class="hero">
<nav>
<h2 class="logo">JAKEISTHATMAN.</h2>
<ul>
<li>
Home
</li>
<li>
About
</li>
<li>
Services
</li>
<li>
Portfolio
</li>
</ul>
<button type="button">Contact</button>
</nav>
</div>
<div class="container"></div>
<div class="main-text">
<h1>
I'm a <span class="type"></span>
</h1>
<p>
Also I work for <b>#no</b> media team!
</p>
<button type="button">Contact</button>
</div>
export default function Typed() {
const TypedElement = useRef(null);
useEffect(() => {
if (!TypedElement.current) return;
const typed = new Typed(TypedElement.current, {
strings: [
"string",
"string2",
"string3",
],
startDelay: 300,
typeSpeed: 100,
backSpeed: 100,
backDelay: 500,
loop: true,
});
// Destroying
return () => {
typed.destroy();
};
}, []);
return <span ref={TypedElement}></span>
}
</body>
</>
);
}
export default HomePage;
First, if the code example above is how your code really is, it won't work because you just have javascript in an html tag all of a sudden. Try wrapping the javascript with curly brackets to let the file know you are typing javascript code now like this:
<div>
{console.log("this is javascript")}
</div>
Second, it looks like you are trying to define a functional component called Typed. At the very least, it is poor organization to define a functional component inside an html tag like you have done above (if it isn't impossible, not sure, never tried it). You should define the functional component called Typed outside the HomePage function, like so:
import "./App.css";
import Typed from "typed.js";
import { useEffect, useRef } from "react";
const Example = ({args_if_necessary}) => {
const typeTarget = useRef(null);
useEffect(() => {
const typed = new Typed(typeTarget.current, {
strings: ["<i>First</i> sentence.", `use ${args_if_necessary}`],
typeSpeed: 40,
});
return () => {
typed.destroy();
};
}, []);
return <span ref={typeTarget} />;
};
function HomePage() {
return (
<>
<body>
<your-other-html />
<Example args_if_necessary={"something"} />
</body>
</>
);
}
export default HomePage;

How to show only texts in react from json data with html tag?

I'm trying to present data and
the json data contains html tags. so it's shown like this in the
browser
<ul><li>Marcus</li><li>19year old</li></ul>
it literally contains html tags as text.
data['id'].map((v)=>(
<div>{v.name}</div>
<div>{v.age}</div>
))
in react how can I show only text?
Ideally you would show us an example of the json data, without seeing that this answer might not be that helpful.
You can use dangerouslySetInnerHTML to render a html string as if it were actually HTML:
const data = [
{ name: "<li>Marcus</li>", age: "<li>19 year old</li>" },
{ name: "<li>Jane</li>", age: "<li>22 year old</li>" }
];
export default function App() {
return (
<div className="App">
{data.map((v) => (
<>
<div dangerouslySetInnerHTML={{ __html: v.name }} />
<div dangerouslySetInnerHTML={{ __html: v.age }} />
</>
))}
</div>
);
}
Codesandbox:
https://codesandbox.io/s/wandering-dream-vhprd?file=/src/App.js
I solved it by using
yarn add react-html-parser
I got an advice from here
Render HTML string as real HTML in a React component
you can use this like below.
import ReactHtmlParser from 'react-html-parser';
const Component = (props) => {
const {data} = props;
return(
<div>{ReactHtmlParser(data.title)}</div>
{/* this will show bold text of hello instead of <b>hello</b> or any
other html form of json data */}
)
}

React mapping fetched data

I'm trying to fetch some data from my database with some simple to-dos. However I cant seem to map them out into a list on my site.
I keep getting errors like: todoFromServer.map is not a function or that todoFromServer is not an array etc.
My current code looks like this:
import apiFacade from "../api/apiFacade";
import React, { useState, useEffect } from "react";
import {Form, FormGroup, Label, Input, Button} from "reactstrap"
export default function SecurePage() {
const [todoFromServer, setTodoFromServer] = useState("Waiting...");
useEffect(() => {
apiFacade.getTodo().then((data) => setTodoFromServer(data));
}, []);
return (
<div className="container-fluid padding">
<div className="row">
<div className="col-3"></div>
<div className="col-6 text-center">
<Form>
<FormGroup>
<h3 className="mt-5">Todos</h3>
<Input type="text" placeholder="Enter Todo"></Input>
</FormGroup>
<Button type="submit">Add</Button>
</Form>
<div>
{todoFromServer.map(() => (
<div>{todoFromServer.todoText}</div>
))}
</div>
</div>
</div>
</div>
);
}
The data I trying to fetch should come out as json looking like this:
I'm kind of lost.. Hope someone can help me out
to be clear - I want the data mapped out on a list with a delete button next to it...
const [todoFromServer, setTodoFromServer] = useState([]); // <=== initialize this as an empty array.
useEffect(() => {
apiFacade.getTodo().then((data) => setTodoFromServer(data)); // Make sure data returned from Promise resolve is indeed an array
}, []);
You want to read todoText of each todo's inside your array item so you would do something like this.
{todoFromServer.length ? todoFromServer.map((todo) => (
<div>{todo.todoText}</div>
)) : "Waiting..."}
For additional reference, take a look at Array.map usage here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Custom HTML attributes on React component

I'm trying to add a custom HTML attribute on a React component:
const Parent = () => (
<div className="parent">
<Child data-custom="foo" />
</div>
);
Where Child is another React component, but the attribute gets stripped on the output HTML. I'm aware that I could simply add the attribute on the Child root element, like so:
const Child = () => <div className="child" data-custom="foo" />
Or read the attribute in the Child component via props, but that's not what i'm looking since that would couple the attribute with the component, and I'm looking for a more contextual approach (the attribute would be used for test automation purposes).
Is there a clean way to do that in React?
I'm also considering writing a Babel plugin to add the attribute or prevent the stripping, but that would be another question.
Thanks!
React element doesn't necessarily correspond to DOM element that could have HTML attributes. React component can be rendered to multiple DOM elements or no elements at all.
If Child should be able to provide additional props or attributes to child DOM element, it should pass them explicitly:
const Child = props => <div className="child" {...props} />
This way data-custom="foo" will be passed to <div>.
For this, you can try this in your react script.
const MyCompo = () => {
return (
<div>
<p>HTML Code</p>
</div>
);
}
export default About;
Otherwise you can create class and then define your components and then export them.
import React from 'react';
import '../assets/css/style.css';
import '../assets/css/pure-min.css';
import '../assets/css/custom.css';
import 'font-awesome/css/font-awesome.min.css';
import $ from 'jquery';
class FirstScreen extends React.Component {
constructor(props) {
super(props);
this.handleLoad = this.handleLoad.bind(this);
}
componentDidMount() {
window.addEventListener('load', this.handleLoad);
}
handleLoad() {
}
render() {
return <div>HTML Code</div>;
}
}
export default FirstScreen;
You could use the below syntax
const Parent = () => (
<div className="parent">
<Child data-custom="foo"/>
</div>
);
const Child = ({...props}) => (<div className="child" {...props} />)

React JSON - Display data in a Card Slider

I have a local JSON file which I've converted to Javascript.
I am able to fetch the data by importing the JS file into my App.js.
This is my App.js file:
import React, { Component } from "react";
import CardData from "./data/db";
import "./App.css";
class App extends Component {
constructor() {
super();
this.state = {
CardData
};
}
render() {
return (
<div>
{this.state.CardData.map(cards => (
<div className="card">
<span>{cards.title}</span>
<br />
<span>{cards.subtitle}</span>
<br />
</div>
))}
</div>
);
}
}
export default App;
I want to be able to show 3 Cards, and then have the option to slide across to the remaining cards.
Something like this
However I am only able to show it in one div, is there a way to do it in the way I've called the JSON or is there a way to separate the JSON data by their ID?
Since you are looking for a simpler way to achieve the same result I would suggest switching your App to a stateless component, as it is never updating/using any state value :
import React from "react";
import CardData from "./data/db";
import "./App.css";
const App = props => (
<React.Fragment> //A fragment will not appear in your DOM
{CardData.map(({ title, subtitle }, index) => ( //Deconstructs each cards
<div className="card" key={index}>
<span>{title}</span>
<br />
<span>{subtitle}</span>
<br />
</div>
))}
</React.Fragment>
)
export default App;
But this component will never be able to render anything else than this specific JSON file, if you want it to be more generic, you should send your data via the component's props :
import React from "react";
import "./App.css";
const App = ({ cards }) => (
<React.Fragment>
{cards.map(({ title, subtitle }, index) => (
<div className="card" key={index}>
<span>{title}</span>
<br />
<span>{subtitle}</span>
<br />
</div>
))}
</React.Fragment>
)
export default App;
And in your parent component :
import CardData from "./data/db";
const Parent = props => <App cards={CardData}/>
You should also not forget about keys when mapping elements, as every mapped component should have a unique and persistent key.