The minified react error instructs me that an "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined."
Looking around, it seems that most people have issues with import/exports and the use of braces when necessary, eg. while using the default keyword.
However, this doesn't seem to be the issue here, which leaves me befuddled.
I have a few components in my program I've included below. None of these seem to strike me as improper importing or importing an undefined element.
How would I go about debugging this? If this is not import related, would it be dependency-related?
Code for reference below:
ExerciseDay:
import React from 'react';
import ExerciseItem from './ExerciseRoutine';
import ProgressionChart from "./ProgressionChart";
import surveyHelp from '../img/chart-help.png';
import surveyHelpText from '../questionnaire/chart-help.json';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
export default class ExerciseDay extends React.Component {
constructor() {
super();
this.state = {help: false, visibility: true};
const experience = localStorage["experience"];
const pageChosen = sessionStorage.getItem("page");
this.numeric = pageChosen ? sessionStorage["page"] : experience === "No" ? "29" : experience === "Yes, once" ? "30" : "31";
this.sheikoData = require("../programs/Sheiko" + this.numeric + ".json");
}
render() {
let exerciseRoutines;
if (this.sheikoData) {
exerciseRoutines = this.sheikoData.map(exerciseDay => {
return (<ExerciseItem key={exerciseDay.day} exerciseDay={exerciseDay}/>);
});
}
return (
<div className="ExerciseDay">
<div style={{textAlign: "center", fontFamily: "Spectral SC", fontSize: 60}}>
Sheiko {!this.numeric.includes('-') ? '#' : null}{this.numeric}</div>
<ProgressionChart data={this.sheikoData}/>
<div className="Survey-help" style={{marginLeft: "5%"}}>
<img id="help-button" src={surveyHelp} alt=""
style={{width: "2%", float: "left", borderRadius: "5px", background: "lightgreen"}}
onClick={() => {
this.setState({help: !this.state.help})
}}/>
<ReactCSSTransitionGroup transitionName="fade" transitionEnterTimeout={300}
transitionLeaveTimeout={500}>
<p style={{
marginLeft: "5%",
fontFamily: "Itim, cursive",
fontSize: 22
}}>{this.state.help ? surveyHelpText.text : null}</p>
</ReactCSSTransitionGroup>
</div>
{exerciseRoutines}
</div>
);
}
}
ExerciseRoutine:
import React from "react";
import ExerciseType from "./ExerciseType";
import show from '../img/show.png';
import hide from '../img/hide.png';
export default class ExerciseRoutine extends React.Component {
constructor() {
super();
this.state = {showExerciseType: true};
}
render() {
let exerciseRoutine;
if (this.props.exerciseDay.routine) {
let routineKey = 0;
exerciseRoutine = this.props.exerciseDay.routine.map(routine => {
return <ExerciseType key={routine.exercise + routineKey++} routine={routine}/>
});
}
return (
<div className="ExerciseRoutine" style={{marginLeft: "15%"}}>
<div>
<h2 style={{
fontFamily: "Arima Madurai, cursive",
fontSize: 30,
display: "inline"
}}>{this.props.exerciseDay.day}
- {this.props.exerciseDay.routine.length} exercises</h2>
<img src={this.state.showExerciseType ? hide : show}
style={{width: this.state.showExerciseType? "2%": "2%", transform: "translateY(22%)"}} alt=""
onClick={() => this.setState({showExerciseType: !this.state.showExerciseType})}/>
</div>
<hr/>
{this.state.showExerciseType ? exerciseRoutine : null}
<br/>
</div>
)
}
}
ExerciseSelector:
import React from "react";
import Select from 'react-select';
import selection from "../programs/SheikoSelector.json";
export default class ExerciseSelector extends React.Component {
render() {
function logChange(val) {
if(!val) return;
sessionStorage["page"] = val.value;
window.location.reload();
}
return (
<Select name="exercise-selector" value="Current" clearValueText="yes"
options={selection} onChange={logChange} autofocus={true}
placeholder="Click here to search Sheiko program..."/>
);
}
}
ExerciseTask:
import React from "react";
import ReactToolTip from 'react-tooltip'
export default class ExerciseTask extends React.Component {
render() {
const effort = this.props.task.effort !== 0 ? Math.round(this.props.task.effort * 100) + "%" : "a comfortable";
return (<li className="ExerciseTask">
{this.props.task.sets} Sets of {this.props.task.reps} reps at {effort} effort
<ReactToolTip/>
</li>);
}
}
and ExerciseType:
import React from 'react';
import ExerciseTask from "./ExerciseTask";
import benchpress from '../img/benchpress.png';
import squat from '../img/squat.png';
import flies from '../img/flies.png';
import abs from '../img/abs.png';
import pushup from '../img/pushup.png';
import other from '../img/other.png';
export default class ExerciseType extends React.Component {
render() {
let exerciseType;
if (this.props.routine.tasks) {
let taskKey = 0;
exerciseType = this.props.routine.tasks.map(task => {
return <ExerciseTask key={taskKey++} task={task}/>
});
}
function determineImage(exercise) {
return exercise.includes("Bench") ? benchpress : exercise.includes("Squat") ? squat : exercise.includes("Fly") ? flies : exercise.includes("Abs") ? abs : exercise.includes("Push up") ? pushup : other;
}
return (<div className="ExerciseType" style={{backgroundColor: "#f9fbff"}}>
<h3 style={{
fontFamily: "Arima Madurai, cursive",
fontSize: 23
}}>{this.props.routine.exercise.charAt(0).toUpperCase() + this.props.routine.exercise.slice(1)}</h3>
<div style={{float: "left", whiteSpace: "nowrap"}}>
{exerciseType}
</div>
<img id="exercise-picture" src={determineImage(this.props.routine.exercise)}
data-tip={this.props.routine.exercise} alt=""/>
</div>);
}
}
Related
I received this error :
Line 21:28: React Hook "useSpring" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks.
I want to make a transition with the opacity and when I click the button appears the image or disappears.
import React, { Component } from 'react';
import { withTranslation } from 'react-i18next';
import { useSpring, config, animated } from "react-spring";
import './Experience.css';
class Experience extends Component {
constructor(props) {
super(props);
this.state = {
showA: false
};
}
render() {
// const [showA, setShowA] = useState(false);
const fadeStyles = useSpring({
config: { ...config.molasses },
from: { opacity: 0 },
to: {
opacity: this.state.showA ? 1 : 0
},
});
return (
<div style={{ padding: "15px" }} className="App">
<h2>Fade Demo</h2>
<div>
<animated.div style={fadeStyles}>
<img src={`https://a.wattpad.com/useravatar/valery2080.256.603024.jpg)`} alt="hola"/>
</animated.div>
<br />
<button onClick={() => this.setState(val => !val)}>Toggle</button>
</div>
</div>
);
}
}
export default withTranslation()(Experience);
You need to convert the class component to a functional component. Following is the implementation of Experience Component to a functional component.
Note: Make sure to add the CSS file in your implementation.
Following is the codesandbox link for your reference: https://codesandbox.io/s/jolly-wescoff-bnqm4
import React, { useState, Component } from "react";
import { withTranslation } from "react-i18next";
import { useSpring, config, animated } from "react-spring";
const Experience = () => {
const [showA, setShowA] = useState(false);
const fadeStyles = useSpring({
config: { ...config.molasses },
from: { opacity: 0 },
to: {
opacity: showA ? 1 : 0
}
});
return (
<div style={{ padding: "15px" }} className="App">
<h2>Fade Demo</h2>
<div>
<animated.div style={fadeStyles}>
<img
src={`https://a.wattpad.com/useravatar/valery2080.256.603024.jpg)`}
alt="hola"
/>
</animated.div>
<br />
<button onClick={() => setShowA(!showA)}>Toggle</button>
</div>
</div>
);
};
export default withTranslation()(Experience);
I have a button that I am using to toggle my sidebar in react application. The toggle button works fine for first two toggle states than it repeats the state twice for third time.
This is how I am toggling state from child component to parent:
import React, { Component } from 'react'
export default class Header extends Component {
constructor(props) {
super(props)
this.state = {
toggle: false
}
}
toggleSidebar = () => {
this.setState({
toggle : !this.state.toggle
});
console.log(this.state.toggle)
this.props.getToggleState(this.state.toggle);
}
render() {
return (
<div>
<button style={{width: '60px'}} onClick={this.toggleSidebar}>Toogle</button>
</div>
)
}
}
export default class App extends Component{
constructor(props) {
super(props)
this.state = {
toggleVal:''
}
}
getData = (val) => {
this.setState({
toggleVal: val
})
}
render(){
let toggleConst = '';
if(this.state.toggleVal){
toggleConst = (
<Router>
<div style={{display: 'flex', backgroundColor: '#ccc', height: '100%', flexDirection:'row'}}>
<div style={{flexDirection:'column'}}>
<Header getToggleState={this.getData}/>
<Routes/>
<Footer/>
</div>
</div>
</Router>
)
}
else{
toggleConst = (
<Router>
<div style={{display: 'flex', backgroundColor: '#ccc', height: '100%', flexDirection:'row'}}>
<SideNav toggleVal={this.state.toggleVal}/>
<div style={{flexDirection:'column'}}>
<Header getToggleState={this.getData}/>
<Routes/>
<Footer/>
</div>
</div>
</Router>
)
}
return (
toggleConst
);
}
}
Toggling the button hides/open the sidebar perfectly but it stuck on state when gets 'false' as twice.
This is how state console goes:
I am not able to find the problem here. Any help appreciated.
App.js
import React, {Component} from 'react';
import { BrowserRouter as Router} from "react-router-dom";
import Header from './Header';
import Sidebar from './Sidebar'
export default class App extends Component{
constructor(props) {
super(props)
this.state = {
toggleVal: false
}
}
getData = (val) => {
this.setState({
toggleVal: val
});
}
render(){
console.log("called.....123...",this.state.toggleVal)
if(this.state.toggleVal){
return (
<Router>
<div style={{display: 'flex', backgroundColor: '#ccc', height: '100%', flexDirection:'row'}}>
<Sidebar toggleVal={this.state.toggleVal}/>
<div style={{flexDirection:'column'}}>
<Header getToggleState={this.getData} />
</div>
</div>
</Router>
)
}
else{
return (
<Router>
<div style={{display: 'flex', backgroundColor: '#ccc', height: '100%', flexDirection:'row'}}>
<Sidebar toggleVal={this.state.toggleVal}/>
<div style={{flexDirection:'column'}}>
<Header getToggleState={this.getData}/>
</div>
</div>
</Router>
)
}
}
}
Header.js
import React, { Component } from 'react'
export default class Header extends Component {
constructor(props) {
super(props)
this.state = {
toggle: false
}
}
toggleSidebar = () => {
this.setState({
toggle: !this.state.toggle
},()=>{
// console.log(this.state.toggle)
this.props.getToggleState(this.state.toggle);
});
}
render() {
return (
<div>
<button onClick={()=>this.toggleSidebar(this.state.toggle)}>Toogle</button>
</div>
)
}
}
Sidebar.js
import React, { Component } from 'react'
import { NavLink } from "react-router-dom";
export default class Sidebar extends Component {
render() {
return (
<>
{
this.props.toggleVal &&
<div className="sidebar_container">
<nav className="nav_container">
<ul>
<li>
<NavLink to="/" activeClassName="active" exact={true}>Dashboard</NavLink>
</li>
<li>
<NavLink to="/user" activeClassName="active">User PRofile</NavLink>
</li>
<li>
<NavLink to="/register" activeClassName="active">Register</NavLink>
</li>
</ul>
</nav>
</div>
}
</>
)
}
}
https://repl.it/repls/IncredibleLinedCgi
This Will Work for You
Change this part of the code:
this.setState({
toggle : !this.state.toggle
});
To this:
this.setState(prev => {
return { toggle : !prev.toggle }
});
You should call getToggleState inside your setState callback in order to use proper state as argument
this.setState(prevState => {
this.props.getToggleState(!prevState.toggle);
return { toggle: !prevState.toggle };
});
Despite this solution, it's better if you don't keep duplicate state in child component <Header /> as conditional render is Parent duty.
This could be much simpler in my opinion.
Define the state on the parent component App ìsToggled
Call from the child component Header via callback this.props.onToggle()
Use conditional rendering on parent component {this.state.isToggled && <Sidebar/>}
import React, {Component} from 'react';
import {BrowserRouter as Router} from "react-router-dom";
import Header from './Header';
import Sidebar from './Sidebar'
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
isToggled: false
}
};
onToggle = () => {
this.setState({
isToggled: !this.state.isToggled
});
console.log(this.state.isToggled);
};
render() {
return (
<Router>
<div style={{display: 'flex', backgroundColor: '#ccc', height: '100%', flexDirection: 'row'}}>
<div style={{flexDirection: 'column'}}>
<Header onToggle={this.onToggle}/>
</div>
{this.state.isToggled && <Sidebar/>}
</div>
</Router>
)
}
}
import React, {Component} from 'react'
export default class Header extends Component {
constructor(props) {
super(props)
}
render() {
return (
<div>
<button onClick={() => {
this.props.onToggle()
}}>Toggle
</button>
</div>
)
}
}
import React, {Component} from 'react'
import {NavLink} from "react-router-dom";
export default class Sidebar extends Component {
render() {
return (
<div className="sidebar_container">
<nav className="nav_container">
<ul>
<li>
<NavLink to="/" activeClassName="active" exact={true}>Dashboard</NavLink>
</li>
<li>
<NavLink to="/user" activeClassName="active">User PRofile</NavLink>
</li>
<li>
<NavLink to="/register" activeClassName="active">Register</NavLink>
</li>
</ul>
</nav>
</div>
)
}
}
I have one question, how to use multiple toggle class
Please check my example below
I want to click <TaxItem /> and add some class to that element, and the second click to remove that class
import React, { Component } from "react";
import TaxItem from "./TaxItems/"
import Pentagon from "../../../assets/images/pentagon.png"
class Taxs extends Component {
constructor(props) {
super(props)
this.state = {
taxStatus: false
}
this.handleTaxStatus = this.handleTaxStatus.bind(this);
}
handleTaxStatus(element) {
console.log('sdasa', element)
}
render() {
return (
<div className="taxs">
<TaxItem
image={Pentagon}
name='Item 1'
taxStatus={false}
handleTaxStatus={this.handleTaxStatus(this)}
/>
<TaxItem
image={Pentagon}
name='Item 2'
taxStatus={false}
handleTaxStatus={this.handleTaxStatus(this)}
/>
</div>
)
}
}
export default Taxs
And here you can check button where I have onClick:
import React, { Component } from "react";
class TaxItem extends Component {
render() {
return (
<div className="tax-item" onClick={this.props.handleTaxStatus}>
<div className={this.props.taxStatus ? 'checked on' : 'checked'}><i className="icon icon-check"></i></div>
<img src={this.props.image} alt="Pentagon" />
<p>{this.props.name}</p>
</div>
)
}
}
export default TaxItem
How I can use THIS, something like jQuery.
As I said in the comment, I would suggest you to not use "THIS", which would mean use the refs, because it would lead to edit the DOM directly, which in React should be avoided when you can.
Instead, you could use an array of taxStatus property, one for each TaxItem, and using them as toggle, something like in the following:
class TaxItem extends React.Component {
localHandleClick = (_) => {
this.props.handleClick(this.props.taxStatusIndex);
};
render() {
const {taxStatus, handleClick} = this.props;
return (
<div
className={"button" + (taxStatus ? " checked" : " not-checked")}
onClick={this.localHandleClick} />
);
}
}
class Taxs extends React.Component {
constructor(props) {
super(props);
const taxItemCounter = props.num;
this.state = {
taxesStatus: new Array(taxItemCounter).fill(false)
}
}
handleClick = (i) => {
const taxesStatus = this.state.taxesStatus;
taxesStatus[i] = !taxesStatus[i];
this.setState({taxesStatus});
}
render() {
return (
<div>
{
this.state.taxesStatus.map((status, index) =>
<TaxItem
key={index}
taxStatusIndex={index}
handleClick={this.handleClick}
taxStatus={status} />
)}
</div>
);
}
}
ReactDOM.render(<Taxs num={3} />, document.getElementById('root'));
#import url(https://fonts.googleapis.com/css?family=Montserrat);
body {
font-family: 'Montserrat', sans-serif;
}
.button {
width: 100px;
height: 25px;
background: red;
margin: 10px;
cursor: pointer;
}
.button.checked {
background: green;
}
<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='root'></div>
Anyways, if you DO want to use "THIS" (which again, would mean using the refs), I can provide you an example.
I am trying to use a component that is already created, but I cant figure out what the problem is:
activetenant
import React, { Component } from 'react';
import authAction from '../../redux/auth/actions';
class ActiveTenant extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div></div>
);
}
}
export default ActiveTenant;
and the component where I am trying to use it
import React, { Component } from "react";
import { connect } from "react-redux";
import { Layout } from "antd";
import appActions from "../../redux/app/actions";
import TopbarUser from "./topbarUser";
import TopbarWrapper from "./topbar.style";
import themes from "../../settings/themes";
import { themeConfig } from "../../settings";
import { ActiveTenant } from "./activetenant";
const { Header } = Layout;
const { toggleCollapsed } = appActions;
const customizedTheme = themes[themeConfig.theme];
class Topbar extends Component {
render() {
const { toggleCollapsed } = this.props;
const collapsed = this.props.collapsed && !this.props.openDrawer;
const styling = {
background: customizedTheme.backgroundColor,
position: "fixed",
width: "100%",
height: 70
};
return (
<TopbarWrapper>
<Header
style={styling}
className={
collapsed ? "isomorphicTopbar collapsed" : "isomorphicTopbar"
}
>
<div className="isoLeft">
<button
className={
collapsed ? "triggerBtn menuCollapsed" : "triggerBtn menuOpen"
}
style={{ color: customizedTheme.textColor }}
onClick={toggleCollapsed}
/>
</div>
<ul className="isoRight">
<li>
<ActiveTenant />
</li>
<li
onClick={() => this.setState({ selectedItem: "user" })}
className="isoUser"
>
<TopbarUser />
</li>
</ul>
</Header>
</TopbarWrapper>
);
}
}
export default connect(
state => ({
...state.App.toJS()
}),
{ toggleCollapsed }
)(Topbar);
And the error
./src/containers/Topbar/Topbar.js 105:34-46 './activetenant' does not
contain an export named 'ActiveTenant'.
You are use export default ActiveTenant In this case code should be like this
import ActiveTenant from "./activetenant";
If you want to export mulitple value then use {} to import
for example
//test.js
var a = "cool";
var b = "dool";
export a;
export b;
import {a,b} from './test.js'
First of all, I want to ask whether is my statement is correct :
"When we are making components, it is better to put it in different files"
Is it correct? since currently I tried so, and it cause problems.
Parents :
import React, { Component } from 'react';
import './App.css';
import {SubmitComponent} from './submitComponent.jsx';
import {topicTable} from './topicTable.jsx';
// import {TopicsContainer} from './TopicsContainer.js'
const dashboardStyle = {
border: '2px solid black',
width: '70%',
height: 'auto',
marginLeft: 'auto',
marginRight: 'auto',
marginBottom: '100px',
};
class AppDashBoard extends Component {
constructor(props) {
super(props);
this.state = {
datas: []
}
}
submitTopic = (data) => {
console.log(data);
console.log(this.state.datas);
console.log(this.state.datas.concat([data]));
this.setState({
datas: this.state.datas.concat(data)
});
console.log(this.state.datas);
}
render() {
return (
<div style={dashboardStyle}>
<h1 style={{textAlign:'center'}}>Coding Exercise</h1>
<hr />
<SubmitComponent submitTopic={this.submitTopic} />
<topicTable topics={this.state.datas} />
</div>
);
}
}
export default AppDashBoard
and this is the topicTable component :
import React, {Component} from 'react';
import {oneTopic} from './oneTopic.jsx';
export class topicTable extends Component {
render() {
const topicstable = this.props.topics.map((topic) => (
<oneTopic
title={topic.title}
desc = {topic.desc}
vote = {topic.vote}
/>
));
console.log("HAHAHAHA");
return (
<div id="topics">
{oneTopic}
</div>
);
}
}
and Lastly, my oneTopic component:
import React, {Component} from 'react';
export class oneTopic extends Component {
render() {
return(
<div style={{width:'96%', height:300, backgroundColor :'#AAA'}}>
<h1>HAHAHAHA</h1>
</div>
);
}
}
My problems are :
1) In the topicTable component, the console.log("HAHAHA") is not executed at all, I wonder why ?
2) Also for the oneTopic, the HAHAHA is not showing at all.
Even I already export and import everything
Please help
ReactJS component names must begin with capital letters.
1) rename oneTopic to OneTopic
2) change {oneTopic} to <oneTopic />