How to get data from json using axios in react? - json

There are two files reactjs.json in which..
{
"642176ece1e7445e99244cec26f4de1f":
["https://ih1.redbubble.net/image.487729686.1469/pp,550x550.jpg",
"https://ik.imagekit.io/PrintOctopus/s/files/1/0006/0158/7777/products/abey_pagal_hai_kya.png?v=1547744758"]
}
and index.html
<!DOCTYPE html>
<html>
<head>
<title>Image Viewer-Static</title>
<!-- <link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"
/>
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.7.2/css/all.css"
/>
<link
rel="stylesheet prefetch"
href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css"
/>
<link rel="stylesheet" href="style.css" /> -->
</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">
var imageslink;
class FetchDemo extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Pictures apikeys="642176ece1e7445e99244cec26f4de1f" />
</div>
);
}
}
class Pictures extends React.Component {
constructor(props) {
super(props);
axios.get('reactjs.json').then(
res => {
console.log(res.data);
imageslink = res.data;
console.log(imageslink);
})
}
render() {
return (
<div>
{imageslink[this.props.apikeys].map(function(name, index){
return <img key={index} src={name} />;
})}
</div>
);
}
}
ReactDOM.render(
<FetchDemo/>,
document.getElementById("root")
);
</script>
</body>
</html>
Error:
Actually I want to fetch data from the reactjs.json file into the index.html using ajax in react. I am using axios for this and for react I am using cdn. But I am unable to fetch the data .
I tried to put it in componentDidMount() in FetchDem class but not works so I PASSED IT INTO THE CONSTRUCTOR but still I am unable to access the data.
So my question is how to acess the data from reactjs.json file to index.html?

React documentation recommends using componentDidMount for API calls.
Also when you fetch the data, you have to keep it in the state. Later the data will be available in the render method.
Here's how you have to tune-up you code:
constructor(props) {
super(props);
this.state = { imageslink: null }
}
componentDidMount() {
axios.get('reactjs.json').then( res => {
this.setState({ imageslink: res.data })
})
}
render() {
const { imageslink } = this.state
if (imageslink) {
// Here you can access this.state.imageslink,
// because they will be fetched.
}
}
Here's a generic Axios React example:
class App extends React.Component {
constructor(props) {
super(props)
this.state = { users: [] }
}
componentDidMount() {
axios.get('https://reqres.in/api/users?page=1')
.then(response => this.setState({ users: response.data.data }))
}
renderUsers() {
const { users } = this.state
return users.map( user => (
<div key={user.id}>{user.first_name} {user.last_name}</div>
))
}
render() {
return <div>{ this.renderUsers() }</div>
}
}
ReactDOM.render(
<App />,
document.getElementById('container')
)
<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>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>

Related

Client side React componentDidMount not called (without JSX)

I am learning React and following their step by step tutorial but without the use of JSX. I am not very far into the tutorial but I hit a snag. The componentDidMount method is not being called, and so my timer does not update.
Any help would be appreciated.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React Test</title>
<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 crossorigin src="assets/react.development.16.4.1.js"></script>-->
<!--<script crossorigin src="assets/react-dom.development.16.4.1.js"></script>-->
</head>
<body>
<div id="root"></div>
<script>
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
message: "Hello World!",
date: new Date(),
}
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
render() {
let fragment = React.createElement(React.Fragment, null, [
React.createElement("h1", {key: "message"}, this.state.message),
React.createElement("p", {key: "time"}, this.state.date.toLocaleTimeString())
]);
return fragment;
}
tick() {
this.setState({
date: new Date()
});
}
}
ReactDOM.render(new App().render(), document.getElementById("root"));
</script>
</body>
</html>
I think the problem is there in one place
ReactDOM.render(new App().render(), document.getElementById("root"));
Why this will not work ?
Because render will return chilren of App component not the App itself
. Your children will be mounted first and your App is neverbe rendered
, hence no componentDidMount for App component
the context is not proper. Try using arrrow funciton here
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
message: "Hello World!",
date: new Date(),
}
}
componentDidMount() {
console.log("mounting")
this.timerID = setInterval(
() => {
this.tick()
},
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
render() {
let fragment = React.createElement(React.Fragment, null, [
React.createElement("h1", {key: "message"}, this.state.message),
React.createElement("p", {key: "time"}, this.state.date.toLocaleTimeString())
]);
return fragment;
}
tick = () => {
debugger
this.setState({
date: new Date()
});
}
}
ReactDOM.render(React.createElement(App), document.getElementById("root"));
<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 crossorigin src="assets/react.development.16.4.1.js"></script>-->
<!--<script crossorigin src="assets/react-dom.development.16.4.1.js"></script>-->
<div id="root"></div>

How to get and pass object(JSON API) in React/Redux?

i have a problem with getting and passing JSON object (info) from Store in React "Container" to his child component (InfoPage) via props..
Also i had Action's and Reducer's methods, all of there works without mistakes.
Could somebody help me with this.
This is my code from "Container".
thanks.
function mapStateToProps(state) {
return {
user: state.auth.user,
info: state.info,
ui: state.ui
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(Object.assign({}, uiActions,
authActions, infoActions), dispatch);
}
class Info extends Component {
static propTypes = {
user: PropTypes.objectOf(PropTypes.any).isRequired,
ui: PropTypes.objectOf(PropTypes.any).isRequired,
info: PropTypes.objectOf(PropTypes.any).isRequired,
switchProfileMenu: PropTypes.func.isRequired,
logOut: PropTypes.func.isRequired,
};
constructor(props) {
super(props);
this.handleClickOption = this.handleClickOption.bind(this);
}
handleClickOption() {
return this.props;
}
render() {
const { user, logOut, info, ui: { showProfileMenu },
switchProfileMenu } = this.props;
return (
<div className={b()}>
<Header
user={user}
logOut={logOut}
switchMenu={switchProfileMenu}
showMenu={showProfileMenu}
/>
<div className="container">
<div className="content">
<div>
<InfoPage data={info} />
sadasd
</div>
</div>
</div>
<Footer />
</div>
);
}
<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>
I gave a look to your code and there are some missing parts.
First, the function getInfo looks to be a thunk (redux-thunk, which allows you to execute asynchronous operations). You have to import it inside your index and initialize it is, not an array
import thunk from 'redux-thunk'
// ...
createStore(rooReducer, applyMiddlewares(thunk))
You can define you mapDispatchToProps in a simple way, for now:
import getInfo from './actions'
// ....
function mapDispatchToProps (dispatch) {
return {
dispatchGetInfo(id) {
dispatch(getInfo(id))
}
}
}
Inside your component Info, implement like this:
componentDidMount () {
const { dispatchGetInfo, params: { id } } = this.props
// I PRESUME your `id` is inside the params of react router, feel free to change if not
dispatchGetInfo(id) // => this should call your thunk which will call your consecutive dispatcher
}
EDIT
Your index file should contain this modified line
<Route name="app:info" path="information/:id" component={Info} />

Cannot read property 'toObject' of undefined when trying to call a func property

This is my component
class MyComponent extends Component {
render () {
const { action } = this.props;
action();
return (<div>Done!</div>);
}
MyComponent.propTypes = {
action: PropTypes.func.isRequired
}
And here is the relevant code of a container:
doSomething () {
...
}
render() {
return (
<MyComponent
action={doSomething}
/>
)
}
When I bring up this code in a browser, I got this error message:
Uncaught TypeError: Cannot read property 'toObject' of undefined
Business logic should live in container so I do not want to copy and paste the code of action into MyComponent.
So my question is: how can I call a function passed in via properties directly in a render method?
I think, issue is in this place:
doSomething () {
...
}
render() {
return (
<MyComponent
action={doSomething} //here
/>
)
}
It should be:
doSomething () {
...
}
render() {
return (
<MyComponent
action={this.doSomething}
/>
)
}
You need to use this.doSomething instead of doSomething.
Check the working example:
class App extends React.Component{
constructor(){
super();
}
doSomething(){
console.log('called');
}
render(){
return(
<div>
Hello
<Child action={this.doSomething}/>
</div>
)
}
}
var Child = (props) => {
const {action} = props
action();
return(
<div>Child</div>
)
}
ReactDOM.render(<App/>, document.getElementById('app'))
<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='app'/>

React: Render JSX repeatedly with multiple onClicks

I followed this stackoverflow answer however i want to know how i can modify this to have it render jsx again & again with multiple clicks
here's a CodePen to show it in action
class NewComponent extends React.Component {
render() {
return (
<div {...this.props}>
new component
</div>
);
}
}
class Button extends React.Component {
render() {
return (
<button {...this.props}>
click
</button>
);
}
}
class App extends React.Component {
constructor() {
super();
this.state = {
clicked: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
clicked: true
});
}
render() {
return (
<div>
<Button onClick={this.handleClick} />
{this.state.clicked ? <NewComponent /> : null}
</div>
);
}
};
ReactDOM.render(
<App />,
document.getElementById("root")
);
<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="root">loading...</div>

React JS Accessing JSON as State

I'm completely brand new to React JS and am trying to create an application that will grab JSON data from a pokemon API, which I will then use to display on screen. Right now, I have it set up so that the user has to input the name of the pokemon they are looking for, i.e. pikachu, and when the search button is pressed, the application will make the API call to return the JSON. I've been searching for the past few days, and cannot seem to find anything to work with the way I currently have my code set up. How do I bind the JSON output to a component that I would then be able to display to the user?
Here's the js code (App.js)
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import ReactDOM from 'react-dom';
class App extends Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Text field value is: ' + this.state.value);
fetch('https://pokeapi.co/api/v2/pokemon/'+this.state.value+'/')
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data.name +" "+ data.id);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
}
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<input type="text"
placeholder="enter name of pokemon here"
value={this.state.value}
onChange={this.handleChange}
/>
<button type="button" onClick={this.handleSubmit}>Search the Pokedex</button>
</div>
);
}
}
export default App;
<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>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tag above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start`.
To create a production bundle, use `npm run build`.
-->
</body>
</html>
Screenshot of issue:
http://imgur.com/a/g9H5r
Try this
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import ReactDOM from 'react-dom';
class App extends Component {
constructor(props) {
super(props);
this.state = {
value: '',
data: {} //filled by fetch data from API
};
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Text field value is: ' + this.state.value);
var _this = this;
fetch('https://pokeapi.co/api/v2/pokemon/'+this.state.value+'/')
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data.name +" "+ data.id);
_this.setState({data: data});
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
_this.setState({data: {}});
});
}
render() {
var data = this.state.data;
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<input type="text"
placeholder="enter name of pokemon here"
value={this.state.value}
onChange={this.handleChange.bind(this)}
/>
<button type="button" onClick={this.handleSubmit.bind(this)}>Search the Pokedex</button>
<h3>{data.id}</h3>
<h3>{data.name}</h3>
</div>
);
}
}
ReactDOM.render(App, document.getElementById("root"));
<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>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tag above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start`.
To create a production bundle, use `npm run build`.
-->
</body>
</html>