componentDidMount unexpected token error [React.js] - javascript

I'm currently working on creating a PokeDex by using the PokeApi. I'm trying to complete the PokemonList, that will contain all the different PokemonCard buttons.
I am receiving expected ";" error for my componentDidMount and I'm unsure why.
The code for the page is
import React from "react";
import PokemonCard from "./PokemonCard";
import "../ui/PokemonList.css";
import axios from 'axios';
export default class PokemonList extends Component {
state = {
url: "https://pokeapi.co.api.v2.pokemon/",
pokemon: null
};
}
componentDidMount() {
const res = axios.get(this.state.url);
this.setState({pokemon: res.data['results'] });
}
const PokeList = () => {
return (
<section className="poke-list">
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
</section>
);
};
//export default PokeList;
It is marking the error on the { symbol after componentDidMount().
The error remains there, even after I add a semi-colon after the curly brackets, even though I don't think the semi-colon is necessary, since the guide I'm following doesn't do it.
Is there some simple rule that I'm breaking? I'm new to React / JavaScript.
edit ----------------------------------------------------
My Dashboard.Js code is
import React, { Component } from "react";
import PokeList from "../pokemon/PokemonList";
export default class Dashboard extends Component {
render() {
return (
<div>
<div className="row">
<div className="col">
<PokeList />
</div>
</div>
</div>
);
}
}
I am getting the following error now
./src/components/layout/Dashboard.js
Attempted import error: '../pokemon/PokemonList' does not contain a default export (imported as 'PokeList').

probably because
import React from "react";
import PokemonCard from "./PokemonCard";
import "../ui/PokemonList.css";
import axios from 'axios';
export default class PokemonList extends Component {
state = {
url: "https://pokeapi.co.api.v2.pokemon/",
pokemon: null
};
} <----- extra curly brace remove this
componentDidMount() {
const res = axios.get(this.state.url);
this.setState({pokemon: res.data['results'] });
}
//keep this function inside class
PokeList = () => {
return (
<section className="poke-list">
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
</section>
);
};
render() {
return(
<div>{this.Pokelist}</div>
)
}}
//export default PokeList; // <=== remove this
Your component did mount was outside the class component.
to make your current code work --
import React from "react";
import PokemonCard from "./PokemonCard";
import "../ui/PokemonList.css";
import axios from 'axios';
export const PokemonList = class PokemonList extends Component {
state = {
url: "https://pokeapi.co.api.v2.pokemon/",
pokemon: null
};
componentDidMount() {
const res = axios.get(this.state.url);
this.setState({pokemon: res.data['results'] });
}
} <==== class component ended
export const PokeList = () => {
return (
<section className="poke-list">
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
<PokemonCard />
</section>
);
};
Dashboard js
import React, { Component } from "react";
import {PokeList} from "../pokemon/PokemonList";
export default class Dashboard extends Component {
render() {
return (
<div>
<div className="row">
<div className="col">
<PokeList />
</div>
</div>
</div>
);
}
}

The first issue is invalid url.
Change url with: https://pokeapi.co/api/v2/pokemon/
See code example:
import React, { Component } from "react";
import ReactDOM from "react-dom";
import PokemonList from "./components/PokemonList";
import "./styles.css";
class App extends Component {
render() {
return (
<div className="App">
<PokemonList />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
import React, { Component } from "react";
import axios from "axios";
import PokemonCard from "./PokemonCard";
class PokemonList extends Component {
constructor(props) {
super(props);
this.state = {
url: "https://pokeapi.co.api.v2.pokemon/",
pokemons: []
};
}
componentDidMount = () => {
axios
.get("https://pokeapi.co/api/v2/pokemon/")
.then(response => {
const data = response.data.results;
this.setState({ pokemons: data });
})
.catch(error => {
console.log(error);
});
};
render() {
const { pokemons } = this.state;
return (
<div className="pokemon-list">
{pokemons.length > 0 &&
pokemons.map(pokemon => {
return <PokemonCard pokemon={pokemon} />;
})}
</div>
);
}
}
export default PokemonList;
import React, { Component } from "react";
class PokemonCard extends Component {
render() {
const { pokemon } = this.props;
console.log(pokemon);
return (
<div className="pokemon-card">
<p>Name: {pokemon.name}</p>
<p>
Url: <a href={pokemon.url}>{pokemon.url}</a>
</p>
</div>
);
}
}
export default PokemonCard;

Related

Changing the image source in a react component

I am getting an error, 'Attempted to assign to readonly property'. I am not sure how to decipher this error message and I feel like my logic looks ok. I am not quite sure where to look.
container component:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { Image } from './Image.js'
import { Button } from './Button.js'
const images = ['https://uploads3.wikiart.org/images/wladyslaw-strzeminski/cover-for-a-book-by-julian-przybo-z-ponad-1930.jpg!Large.jpg',
'https://uploads6.wikiart.org/images/pablo-picasso/girl-on-the-ball-1905.jpg!Large.jpg',
'https://uploads8.wikiart.org/images/salvador-dali/et-post-buccellam-introivit-in-eum-satanas-psalms-40-10-1964.jpg']
class Game extends React.Component{
constructor(props){
super(props)
this.state = {
currentImg: 0
}
this.handleClick = this.handleClick.bind(this)
}
handleClick(){
const current = this.state.currentImg; <--------- error points to this
const next = ++current % images.length;
this.setState({
currentImg: next
})
}
render(){
let src = this.state.currentImg;
return(
<div>
<Image src={images[src]} />
<Button onClick={this.handleClick} />
</div>
)
}
}
ReactDOM.render(
<Game />,
document.getElementById('root')
);
presentational components:
Button:
import React from 'react';
export const Button = (props) => {
return <button onClick={props.onClick}></button>
}
Image:
import React from 'react';
export const Image = (props) => {
return (
<div className="flex-main-item">
<img className="mainImage" src={props.src} />
</div>
)
}

React Props for Handle Change not a Function

I'm getting props.handleChange is not a function when running the following code. I'm trying to update the state when the checkbox is clicked. The field that is check box is called myNetwork. I thought that when NetworkArray component, which is a parent of Card component, would have access to the functions and state in App? But this is my first React App. Please, what am I doing wrong?
App.JS
import React, {Component} from 'react';
import SignUp from './components/SignUp';
import NetworkArray from './components/NetworkArray';
import {network} from './NetworkData'
import './App.css';
import 'tachyons';
class App extends Component {
constructor() {
super()
this.state = {
network: network,
}
this.handleChange=this.handleChange.bind(this);
}
handleChange(id) {
this.setState(prevState => {
const updatedNetwork = prevState.network.map(netw => {
if (netw.id===id) {
netw.myNetwork = !netw.myNetwork
}
return netw
})
return {
network:updatedNetwork
}
})
}
render() {
return (
<div>
<NetworkArray
network={network}
handleChange = {this.handleChange} />
</div>
);
}
}
export default App;
Card.js
import React from 'react';
const Card = (props) => {
return(
<div className = 'bg-light-green dib br3 pa3 ma2 grow shadow-5'>
<div>
<h3>{props.name}</h3>
<p>{props.company}</p>
<p>{props.phone}</p>
<p>{props.email}</p>
<p>{props.city}</p>
</div>
<div>
MyNetwork
<input
type = "checkbox"
checked={props.myNetwork}
onChange={()=> props.handleChange(props.id)}
/>
</div>
</div>
)
}
export default Card;
NetworkArray.js
import React, {Component} from 'react';
import Card from './Card';
const NetworkArray = ({network}) => {
const cardComponent = network.map((user,i) => {
return(
<Card
key = {network[i].id}
name = {network[i].firstName + ' ' + network[i].lastName}
company = {network[i].company}
phone= {network[i].phone}
email={network[i].email}
city = {network[i].city}
/>
)
})
return (
<div>
{cardComponent}
</div>
)
}
export default NetworkArray;
You passed the function from App component to NetworkArray component, but not to Card component.
const NetworkArray = ({network, handleChange}) => {
...
<Card
handleChange={handleChange}
...
/>
}

How do I add router links in reactjs

I was following a tutorial where you could take the star wars api and fetch data from the api to show on the website. In the tutorial, they basically show you to make a button and when you click the button, it shows the character info. But I want it to go to another page showing the details of the character using react router. Below is the code
import axios from 'axios';
import './App.css';
import List from './List';
class App extends Component {
constructor(props){
super(props);
this.state={
people: [],
}
this.getPeople=this.getPeople.bind(this);
}
getPeople(){
return axios.get("https://swapi.co/api/people")
.then((response)=>{
console.log(response.data.results);
this.setState({people: response.data.results})
})
}
componentDidMount(){
this.getPeople()
}
render(){
const {people}=this.state;
return (
<div className="App">
<List people={people}/>
</div>
);
}
}
export default App;
List.js
import React, {Component} from 'react';
import CharInfo from './CharInfo';
class List extends Component{
render(){
const people=this.props.people;
return (
<div className="">
{
people.map((p)=>{
console.log(p)
return (
<div key={p.url}>
<h1 className="char-name">{p.name}</h1>
<CharInfo charInfo={p}/>
</div>
)
})
}
</div>
);
}
}
export default List;
CharInfo.js
import React, {Component} from 'react';
class CharInfo extends Component{
constructor(props){
super(props);
this.state={
expanded: false,
}
this.open=this.open.bind(this);
this.close=this.open.bind(this);
}
open(){
this.setState({expanded: !this.state.expanded})
}
close(){
this.setState({expanded: !this.state.expanded})
}
render(){
const info=this.props.charInfo;
if(!this.state.expanded){
return <p className="btn btn-info" onClick={this.open}>Show info</p>
}
return (
<div className="user-details">
<p className="btn btn-danger" onClick={this.close}>Hide Info</p>
<ul>
<li>
<h2>Gender: {info.gender}</h2>
</li>
<li>
<h2>Birth Year: {info.birth_year}</h2>
<li><h2>Hair Color: {info.hair_color}</h2></li>
</li>
</ul>
</div>
)
}
}
export default CharInfo;
in this link, you could see the code in a codesandbox
https://codesandbox.io/s/romantic-pine-lmhvn
You need to integrate the react-router-dom library in order to navigate to different "pages" in your React application.
Working codesandbox: https://codesandbox.io/s/star-wars-api-8bbuf
App.js
import React, { Component } from "react";
import axios from "axios";
import List from "./List";
import Character from "./Character";
import { BrowserRouter, Route } from "react-router-dom";
class App extends Component {
constructor(props) {
super(props);
this.state = {
people: []
};
this.getPeople = this.getPeople.bind(this);
}
getPeople = () => {
axios.get("https://swapi.co/api/people").then(response => {
this.setState({ people: response.data.results });
});
};
componentWillMount() {
this.getPeople();
}
render() {
const { people } = this.state;
console.log(people);
return (
<BrowserRouter>
<Route
path="/"
exact
render={props => <List {...props} people={this.state.people} />}
/>
<Route
path="/char/:charName"
render={props => {
const { charName } = props.match.params;
const foundCharacter = this.state.people.find(
person => person.name.split(" ").join("") == charName
);
return <Character {...props} info={foundCharacter} />;
}}
/>
</BrowserRouter>
);
}
}
export default App;
CharInfo.js
import React, { Component } from "react";
import { Link } from "react-router-dom";
class CharInfo extends Component {
constructor(props) {
super(props);
this.state = {
expanded: false
};
this.open = this.open.bind(this);
this.close = this.open.bind(this);
}
open() {
this.setState({ expanded: !this.state.expanded });
}
close() {
this.setState({ expanded: !this.state.expanded });
}
render() {
const info = this.props.charInfo.name.split(" ").join("");
return (
<div className="user-details">
<Link className="btn btn-info" to={`/char/${info}`}>
Show info
</Link>
</div>
);
}
}
export default CharInfo;
New component: Character.js
const Character = ({ info }) => {
return (
<div>
{
<ul>
<li>
<h2>{info.name}</h2>
</li>
<li>
<h2>Gender: {info.gender}</h2>
</li>
<li>
<h2>Birth Year: {info.birth_year}</h2>
</li>
<li>
<h2>Hair Color: {info.hair_color}</h2>
</li>
{info.vehicles.length > 0 && (
<li>
<h2>Vehicles:</h2>
<ul>
{info.vehicles.map((vehicle, index) => (
<li key={index}>{vehicle}</li>
))}
</ul>
</li>
)}
</ul>
}
</div>
);
};
export default Character;

React-Paginate is not clickable

I have been trying to use React-paginate library for pagination, however, the buttons formed by it is not clickable,i don't understand what i am doing wrong
And there are no example given, or no question asked
What would be the correct way of using this pagination
Here is the code of my App.js
import React, { Component } from 'react';
import './App.css';
import Navbar from '../src/components/navbar/navbar'
import SearchIt from '../src/components/searchField/search'
import Container from 'react-bootstrap/Container'
import Card from '../src/components/cards/cards'
import Axios from 'axios'
import Pagination from '../src/components/pagination/paginating'
class App extends Component {
state={
fetchedData:[]
}
componentDidMount(){
Axios.get('http://localhost:3000/1').then((responseData)=>{
//console.log(responseData.data)
this.setState({fetchedData:responseData.data})
}).catch((err)=>{
console.log(err)
})
}
handlePageClicked = data => {
let selected = data.selected;
console.log(selected)
};
render() {
return (
<div className="App">
<Navbar/>
<Container>
<SearchIt/>
<Card data={this.state.fetchedData}/>
<Pagination handlePageClick={this.handlePageClicked}/>
</Container>
</div>
);
}
}
export default App;
And here is the code for paginating.js
import React,{Component} from 'react'
import ReactPaginate from 'react-paginate';
import './paginateStyle.css'
const page = (props)=>{
return(
<ReactPaginate
previousLabel={'previous'}
nextLabel={'next'}
breakLabel={'...'}
breakClassName={'break-me'}
pageCount={10}
marginPagesDisplayed={2}
pageRangeDisplayed={5}
onPageChange={props.handlePageClick}
containerClassName={'pagination'}
subContainerClassName={'pages pagination'}
activeClassName={'active'}
/>
)
}
export default page
These button are not clickable
I did a quick sample and it worked.
import ReactPaginate from 'react-paginate';
const Pagination = (props) => {
return (
<ReactPaginate
previousLabel={'previous'}
nextLabel={'next'}
breakLabel={'...'}
breakClassName={'break-me'}
pageCount={10}
marginPagesDisplayed={2}
pageRangeDisplayed={5}
onPageChange={props.handlePageClick}
containerClassName={'pagination'}
subContainerClassName={'pages pagination'}
activeClassName={'active'}
/>
)
}
class App extends Component {
state = {
selectedPage: 0
}
handlePageClicked = data => {
let selected = data.selected;
this.setState({
selectedPage: selected
})
console.log(selected)
};
render() {
return (
<React.Fragment>
<div>You selected: {this.state.selectedPage}</div>
<div className="App">
<Pagination handlePageClick={this.handlePageClicked} />
</div>
</React.Fragment>
);
}
}
There could be something in paginateStyle.css which is making the Pagination not work properly or some other CSS in your application.
EDIT:
From comments, a ui component with higher z index was over them and was not visible/clickable

React-router-dom - Link change url but does not render

I'm new to React and I've made a <Link>to go to next or previous item from dy datas(for example, if i am on user/2 view, previous link go to user/1 and next link go to user/3), the url is correctly changed but the component is not rendered at all and the datas are not reloaded at all.
I've read that it's due to the component not detecting that the children is not changing state so the parent component does not render.
I've tried to use withRouter but I've got a error : You should not use <Route> or withRouter() outside a <Router> and I'm not understanding what I'm doing so if someone has the solution and some explanation to it I would be grateful :)
App.js :
import React, { Component } from 'react';
import {
Route,
Switch,
withRouter,
} from 'react-router-dom';
import HomePage from './pages/home';
import SinglePage from './pages/single';
class App extends Component {
render() {
return (
<Switch>
<div>
<Route exact path="/" component={HomePage} />
<Route path="/:id" component={SinglePage} />
</div>
</Switch>
);
}
}
export default withRouter(App);
Single.js :
import React, { Component } from 'react';
import Details from '../components/details'
import Header from '../components/header'
import { ProgressBar } from 'react-materialize';
class SinglePage extends Component {
constructor(props) {
super(props);
this.state = {
data: { data: null },
}
}
componentDidMount() {
fetch(`http://localhost:1337/${this.props.match.params.id}`)
.then((res) => res.json())
.then((json) => {
this.setState({
data: json,
});
});
}
render() {
const { data } = this.state;
return (
<div>
<h2> SinglePage </h2>
{!data ? (
<ProgressBar />
) : (
<div>
<Header id={this.props.match.params.id} />
<Details item={data} />
</div>
)}
</div>
);
}
}
export default SinglePage;
Header.js :
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link, withRouter } from 'react-router-dom';
class Header extends Component {
static propTypes = {
item: PropTypes.shape({
data: PropTypes.string.isRequired,
}).isRequired,
}
render() {
const prev = parseInt(this.props.id) - 1
const next = parseInt(this.props.id) + 1
return (
<div>
<Link to="/"> Retour </Link>
<Link to={`/${prev}`}> Précédent </Link>
<Link to={`/${next}`}> Suivant </Link>
</div>
)
}
}
export default Header;
the solution is pretty-simple. All you need to do is make use of componentWillReceiveProps and check if the param updated, if it did fetch the data again
componentDidMount() {
this.getData(this.props.match.params.id);
}
componentWillReceiveProps(nextProps) {
if(this.props.match.params.id !== nextProps.match.params.id) {
this.getData(nextProps.match.params.id);
}
}
getData = (param) => {
fetch(`http://localhost:1337/${params}`)
.then((res) => res.json())
.then((json) => {
this.setState({
data: json,
});
});
}

Categories