How to pass a json array in react? - reactjs

First of all I want to clear this I am using cdn for react and using ajax for fetching the details from the json file.
So,I have a json file reactjs.json which looks like...
[
{
"e64fl7exv74vi4e99244cec26f4de1f":[ "image_1.jpg","image_2.jpg"]
}
]
index.html
<!DOCTYPE html>
<html>
<head>
<title>Image Viewer-Static</title>
</head>
<body>
<div id="root"></div>
<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>
<script src="https://unpkg.com/babel-standalone#6.15.0/babel.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/babel">
class FetchDemo extends React.Component {
constructor(props) {
super(props);
this.state = {
images: []
};
}
componentDidMount() {
axios.get('reactjs.json').then(res => {
console.log(res.data);
this.setState({ images: res.data });
});
}
render() {
const { images } = this.state;
return (
<div>
{this.state.images.map((images, index) => (
<PicturesList key={index} apikeys={images.e64fl7exv74vi4e99244cec26f4de1f} />
))}
</div>
);
}
}
class PicturesList extends React.Component {
render() {
return (
<img src={this.props.apikeys} alt={this.props.apikeys}/>
);
}
}
ReactDOM.render(
<FetchDemo/>,
document.getElementById("root")
);
</script>
</body>
</html>
I want to show the image named image_1.jpg,image_2.jpg but this.props.apikeys fetch the value like image_1.jpg,image_2.jpg
images
But I want that it gives two values and show the two image.
I tried a lot to solve this but fails.Any suggestion and help will be welcomed.

Here you are setting the array [ "image_1.jpg","image_2.jpg"] to apiKeys in
<PicturesList key={index} apikeys={images.e64fl7exv74vi4e99244cec26f4de1f} />
So when you try to set the image src here
<img src={this.props.apikeys} alt={this.props.apikeys}/>
what you are setting as this.props.apikeys to src is an array. You have to handle the two images in the array separately to set the source of each image as a String. Try as follows.
{this.props.apikeys.map((image, index) => (
<img src={image} alt={image}/>
))}

since you already have the json file in the file structure you can just import and use it..
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
import reactjsJSON from "./reactjs.json";
class FetchDemo extends React.Component {
constructor(props) {
super(props);
this.state = {
images: reactjsJSON
};
}
** Edit: **
Your html file
<!DOCTYPE html>
<html>
<head>
<title>Image Viewer-Static</title>
</head>
<body>
<div id="root"></div>
<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>
<script src="https://unpkg.com/babel-standalone#6.15.0/babel.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/babel">
class FetchDemo extends React.Component {
constructor(props) {
super(props);
this.state = {
images: []
};
}
componentDidMount() {
axios.get('/reactjs.json').then(res => {
console.log(res.data);
this.setState({ images: res.data });
});
}
render() {
const { images } = this.state;
return (
<div>
{ this.state.images.map(imageObjs =>
Object.keys(imageObjs).map(key =>
imageObjs[key].map((image, index) => (
<PicturesList key={index} apikeys={image} />
))
)
)}
</div>
);
}
}
class PicturesList extends React.Component {
render() {
console.log(this.props)
return (
<img src={this.props.apikeys} alt={this.props.apikeys}/>
);
}
}
ReactDOM.render(
<FetchDemo/>,
document.getElementById("root")
);
</script>
</body>
</html>
Your JSON, tested for all possibilities, replaced with dummy images
[
{
"e64fl7exv74vi4e99244cec26f4de1f": [
"https://picsum.photos/200?image=2",
"https://picsum.photos/200?image=2"
],
"e64fl7exv74vi4e99244cec26f4deop": [
"https://picsum.photos/200?image=2",
"https://picsum.photos/200?image=2"
]
},
{
"e64fl7exv74vi4e99244cec26f4de1g": [
"https://picsum.photos/200?image=2",
"https://picsum.photos/200?image=2"
]
}
]
serve both the files in same http server and check the output.... since both files are served from same server u can add './' path to fetch and get JSON data...

Looks to me like you are receiving this JSON repose & then setting a JSON object into your state. Try looking at
JSON.parse()
. Your also setting the whole JSON object to your images array. You need select a key.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse

I write a demo in codesandbox: https://codesandbox.io/s/oorn5o162q, you can check it out.
I use two real image urls in json, and refine your component code.

Related

what's the use of getDerivedStateFromProps (or how do you fire it?)

I have the following 'List' component where I'm trying to update this.state from props. I can't seem to get getDrivedStateFromProps to work correctly with componentDidUpdate. There's a problem with the logic but it doesn't seem that gDSFC ever fires as I get the same response whether it's commented out or not.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>list</title>
<script src="react/react.js"></script>
<script src="react/react-dom.js"></script>
<script src="https://unpkg.com/babel-standalone#6.15.0/babel.min.js"></script>
</head>
<body>
<div id='container'>
</div>
</body>
</html>
<script type = 'text/jsx'>
class FilteredList extends React.Component{
constructor(props){
super(props);
this.state={list:this.props.list};
}
filter(input){
var newList = this.state.list.filter(function(item){
return (item.search(input.target.value)!=-1);
});
this.setState({list:newList});
}
render(){
return(
<div>
<input type='text' placeholder='Filter' onChange={this.filter.bind(this)} />
<List items={this.state.list} />
</div>
);
}
}
class List extends React.Component{
constructor(props){
super(props);
this.state={items:this.props.items};
}
static getDerivedStateFromProps(nextProps, prevState) {
console.log('hello1');
if (nextProps.items !== prevState.items) {
return {
items: nextProps.items,
};
}
// Return null if the state hasn't changed
return null;
}
componentDidUpdate(nextProps,prevState){
console.log('hello2');
if(nextProps.items !== prevState.items)
this.setState({items:nextProps.items});
}
render(){
return(
<ul>
{this.state.items.map(function(item){
return(<li key={item}>{item}</li>);
})}
</ul>
);
}
}
ReactDOM.render(
<div><FilteredList list={['anteater','bear','cat','dog','elephant','fox']} /></div>,
document.getElementById('container')
);
</script>
Upgrade to v5.2.1 or higher and this open issue should be fixed
yarn upgrade -L react-helmet
I think you need 16.3.1 or later, possibly 16.3.3

How to add multiple React components to HTML

I wonder if we can add multiple react components into HTML without having the related files usually downloaded with npm, or added to a normal HTML but we add a certain component for a chat app as my attempt here, here is a long example:
<html lang="en">
<head>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<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>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class App extends React.Component{
state={
messages:[
{ }
],
userId:''
}
addMessage=(message)=>{
message.num = Math.random();
message.id=this.state.messages.id;
let messages = [...this.state.messages, message];
this.setState({
messages })
}
addId=(userId)=>{
this.setState({
userId
})
}
render() {
return (
<div className="appContainer">
<User userId={this.addId} />
<TopSection Users={this.state.userId}/>
<Messages userId = {this.state.userId} messages={this.state.messages}/>
<AddMessage addMessage={this.addMessage} />
</div>
);
}
}
}
const Messages = ({messages, userId}) =>{
const messageList= (messages.length)? (messages.slice(1).map(message=>{
return(
<div className="message" key={message.num}>
<span key={userId.num}>{message.content?(userId):(null)}</span>
<p>{message.content}</p>
</div>
)
})) : (null);
return(
<div className="textContainer">
{messageList}
</div>
)
}
ReactDOM.render(<App />, document.getElementById('app'));
</script>
</body>
</html>
please let me know if there is away to get this to work.
You mean add components to different dom nodes ?
import {render} from 'reactDOM'
import React from 'react'
import AppOne from './appOne'
import AppTwo from './appTwo'
render(<AppOne />, document.getElementById('appOne'));
render(<AppTwo />, document.getElementById('appTwo'));
React v16 has portals as well for adding componnets to differnt parts of the dom tree

How to use React.Component with renderToString method?

I tried to do the server side render using renderToString method.
function handleRender(req, res) {
const html = renderToString(
<Counter />
);
res.send(renderFullPage(html));
}
function renderFullPage(html) {
return `
<!doctype html>
<html>
<head>
<title>React Universal Example</title>
</head>
<body>
<div id="app">${html}</div>
<script src="/static/bundle.js"></script>
</body>
</html>
`
}
If the component like following it works:
Counter.js
const Counter = () => {
function testClick(){
console.log('test');
}
return (
<div>
<div onClick={testClick.bind(this)}>
test
</div>
</div>
);
};
export default Counter;
However, if I change Counter.js into following:
class Counter extends React.Component {
testClick(){
console.log('click');
}
render() {
return (
<div>
<div onClick={this.testClick.bind(this)}>
test btn
</div>
</div>
)
}
}
export default Counter;
It will show errors:
Uncaught Error: locals[0] does not appear to be a `module` object with Hot Module replacement API enabled. You should disable react-transform-hmr in production by using `env` section in Babel configuration.
So how to use React.Component with renderToString method?
I minimize the project and push to Github. Please have a look.
https://github.com/ovojhking/ssrTest/tree/master

React - Coding Error

I am following tutorial from: https://www.youtube.com/watch?v=OzqR10jG1pg
Using Code Editor: https://stackblitz.com
Coding error reads:
Error in index.js (36:10)
'}' expected.
Error line reads:
render: function () {
How do I get this code to work?
Here is my Code:
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
render() {
return (
<div>
<Hello name={this.state.name} />
<p>
Start editing to see some magic happen :)
</p>
</div>
);
}
}
render(<App />, document.getElementById('root'));
<div id="example"></div>
<script type="text/babel">
var Bacon = React.createClass({
render: function () {
return (<h3>This is a simple component!</h3>);
}
});
ReactDOM.render(<Bacon />, document.getElementById('example'));
</script>
It looks like you are putting HTML code into your javascript (index.js) file. You should have a separate HTML file for that.
I can see you are trying to render two different apps.
First, when you use ReactDOM.render(<Bacon />, document.getElementById('example')); you're telling React to render the component Bacon in the HTML element that has an ID attribute 'example'.
Then, with render(<App />, document.getElementById('root'));, React will look for an element that has an ID attribute 'root'.
So you should have both elements in your HTML file, like the snippet below.
// index.js
class App extends React.Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
render() {
return (
<div>
<div>{this.state.name}</div>
<p>
Start editing to see some magic happen :)
</p>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<!-- index.html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="example"></div>
<div id="root"></div>
<script type="text/babel">
var Bacon = React.createClass({
render: function () {
return (<h3>This is a simple component!</h3>);
}
});
ReactDOM.render(<Bacon />, document.getElementById('example'));
</script>

integrating js code inside react component

I have converted a component that displays chart bar, and it requires this js snippet to run, what is the correct way of integrating it inside my JSX code?
<script>
/** START JS Init "Peity" Bar (Sidebars/With Avatar & Stats) from sidebar-avatar-stats.html **/
$(".bar.peity-bar-primary-avatar-stats").peity("bar", {
fill: ["#2D99DC"],
width: 130,
})
</script>
I have seen this libraries on npm website, but they mostly deal with external scripts not internal
here is my component:
import React, { Component } from 'react';
export default class App extends Component {
render() {
return (
<div>
"How can I render js code here?"
</div>
);
}
}
You can use refs and componentDidMount callback in order to initialize jquery plugins, like so
class App extends React.Component {
componentDidMount() {
$(this.barChart).peity("bar", {
fill: ["#2D99DC"], width: 130
});
}
render() {
return <div>
<div ref={ (node) => { this.barChart = node } }>
<span class="bar">5,3,9,6,5,9,7,3,5,2</span>
<span class="bar">5,3,2,-1,-3,-2,2,3,5,2</span>
<span class="bar">0,-3,-6,-4,-5,-4,-7,-3,-5,-2</span>
</div>
</div>;
}
}
ReactDOM.render(
<App />,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/peity/3.2.1/jquery.peity.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
You should use componentDidMount lifecycle hook.
Add this to your component code:
componentDidMount() {
$(".bar.peity-bar-primary-avatar-stats").peity("bar", {
fill: ["#2D99DC"],
width: 130,
})
}

Resources