Error: Super expression must either be null or a function - reactjs

Problem
So as the title said i've this issue in a todoapp. i checked if i had some typo like react instead of React and it seems to be alright.
Before post something i checked:
First post stackoverflow
Second post stackoverflow
but i cannot find a solution
Code
App.js
import React, {Component} from 'react';
import Form from './Components/Form';
import Footer from './Components/Footer';
import Header from './Components/Header';
class App extends React{
constructor(props) {
this.state = {
todoValue: "",
filterType: "All",
todos: [],
}
}
handleChange = (event) => {
this.setState({
todoValue: event.target.value,
})
}
handleClick = (event) => {
event.preventDefault();
if (this.state.todoValue !== "") {
const todo = {
id: Date.now(),
text: this.state.todoValue,
done: false,
}
this.setState({
todoValue: "",
todos: [todo, ...this.state.todos],
})
}
}
handleToggle = (id) => {
this.setState((prevState) => {
return {
todos: prevState.todos.map((item, i) => {
if (item.id === id) {
return {
...item,
done: !prevState.todos[i].done,
}
}
return item;
})
}
})
}
handleDelete = (id) => {
this.setState({
todos: this.state.todos.filter(item => item.id !== id)
})
}
deleteCompleted = () => {
this.setState({
todos: this.state.todos.filter(item => !item.done)
})
}
getVisibleTodos = () => {
const filterType = this.state.filterType;
let filterState = null;
switch (filterType) {
case "Completed":
return filterState = this.state.todos.filter(item => item.done);
case "Active":
return filterState = this.state.todos.filter(item => !item.done);
case "Originals":
return filterState = this.state.todos.filter(item => !item.done);
case "New":
return filterState = this.state.todos.filter(item => !item.done);
default:
return filterState = this.state.todos;
}
}
setActiveFilter = (text) => {
this.setState({
filterType: text,
})
}
render() {
return (
<div className="container">
<Header countTodo={this.state.todos.length}/>
<Form handleDelete={this.handleDelete}
handleToggle={this.handleToggle}
handleClick={this.handleClick}
handleChange={this.handleChange}
todoValue={this.state.todoValue}
todos={this.getVisibleTodos()}/>
<Footer setActiveFilter={this.setActiveFilter}
deleteCompleted={this.deleteCompleted}
filter={this.state.filterType}/>
</div>
)
}
}
export default App;
Header.js
import React from 'react';
class Header extends React.Component {
render() {
return (
<header className="header">
<h3>All To-Do {this.props.countTodo}</h3>
</header>
)
}
}
export default Header;
Form.js
import React, {Component} from'react';
import Todo from './Todo';
class Form extends React {
render() {
return (
<form className="form">
<input type="text"
className="form__input"
placeholder="Items"
onChange={this.props.handleChange}
value={this.props.todoValue}
/>
<button
className="form__button"
type="submit"
onClick={this.props.handleClick}>╋</button>
<Todo
todos={this.props.todos}
handleToggle={this.props.handleToggle}
handleDelete={this.props.handleDelete}
/>
</form>
)
}
}
export default Form;
and the last modul is Todo.js
import React, {Component} from 'react';
class Todo extends React{
render() {
return (
<ul className="todos-list">
{
this.props.todos.map((item) => {
return (
<li className="todo-item"
key={item.id} onClick={() => this.props.handleToggle(item.id)}>
<span
className={item.done ? "todo-item__name disabled" : "todo-item__name"}>
{item.text}
</span>
<span
className="todo-item__delete-button"
onClick={() => this.props.handleDelete(item.id)}>
×
</span>
</li>
)
})
}
</ul>
)
}
}
export default Todo;

You class should extend from Component that you're importing from react library.
It should be either
class App extends Component{}
or if you didn't import Component then
class App extends React.Component{}

You haven't extended your App component correctly
class App extends React{ // error here
constructor(props) {
this.state = {
todoValue: "",
filterType: "All",
todos: [],
}
}
Extend it from React.Component
class App extends React.Component {
constructor(props) {
super(props); // use super here
this.state = {
todoValue: "",
filterType: "All",
todos: [],
}
}

Related

My checkbox is not changing from check or uncheck, but I can see that state value is changing, what's going on?

So when I run this and check the checkbox, I can see the values changing in the state, but why is the checkbox control not changing its status from check/uncheck? I know the render() method is being hit as well. Why, oh why, Gods of code? Lost in hours of figuring out what's wrong and I'm lost!
bob-Todos.js FILE
class Todo extends React.Component {
constructor(param) {
super();
this.state = {
id: param.data.id,
text: param.data.text,
completed: param.data.completed,
onMyChange: param.OnChange,
};
}
render() {
console.log("In TODO Render");
return (
<div>
<p>
<input
type="checkbox"
onChange={() => {
this.state.onMyChange(this.state.id);
}}
checked={this.state.completed}
/>
{this.state.text}
</p>
</div>
);
}
}
export default Todo;
Bob-App.js FILE
import React, { Component } from "react";
import Todo from "./bob-Todo";
import todoData from "../data/bob-todosData";
class App extends Component {
constructor() {
super();
this.state = { data: todoData };
this.OnChange = this.OnChange.bind(this);
}
OnChange(myId) {
this.setState((prev) => {
let updatedTodos = prev.data.map((todo) => {
if (todo.id === myId) {
todo.completed = !todo.completed;
}
return todo;
});
return { data: updatedTodos };
});
console.log(this.state.data);
}
render() {
return this.state.data.map((item) => {
return <Todo key={item.id} data={item} OnChange={this.OnChange} />;
});
}
}
export default App;
bob-todosData.js FILE
const todosData = [
{
id: 1,
text: "take out the trash",
completed: true
},
{
id: 2,
text: "rest for a while and relax",
completed: false
},
{
id: 3,
text: "watch an online movie",
completed: true
}
]
export default todosData
index.js FILE
import React from 'react';
import ReactDOM from 'react-dom';
import AppBob from "./bobComponents/Bob-App";
ReactDOM.render(
<AppBob />, document.getElementById('root')
);
You don't need to assign your props to state in your Todo component
Just remove them and invoke the function also use those variables directly:
Then your component will be:
class Todo extends React.Component {
render() {
const {
data: {
id,
text,
completed,
},
OnChange, // <-- Should rename this to "onChange"
} = this.props;
console.log('In TODO Render');
return (
<div>
<p>
<input
type="checkbox"
onChange={() => {
OnChange(id);
}}
checked={completed}
/>
{text}
</p>
</div>
);
}
}
export default Todo;
Also, rename your OnChange function to onChange to enable js convention

react twilio video: first joiner screen black on participant join

i have made a twillio video app.i can show local video on Laptop website but when i join from another chrome tab or mobile phone chrome browser the video on laptop goes black and only one video is showing whereas both videos should show properly.i am following this tutorial
https://www.twilio.com/blog/build-a-custom-video-chat-app-with-react-and-twilio-programmable-video
here is my code
App.js
import './App.scss';
import React, {Component} from 'react';
import Room from './Components/Room';
const { connect } = require('twilio-video');
const Token = {"identity":"Jose Corkery","token":"...sioAMt4..."}
class App extends Component {
constructor(props) {
super(props)
this.state = {
identity: '',
room: null
}
this.inputRef = React.createRef();
this.joinRoom = this.joinRoom.bind(this);
this.returnToLobby = this.returnToLobby.bind(this);
this.updateIdentity = this.updateIdentity.bind(this);
this.removePlaceholderText = this.removePlaceholderText.bind(this)
}
async joinRoom() {
try {
// const response = Token
// const data = await response.json();
const room = await connect(Token.token, {
name: 'cool-room',
audio: true,
video: true
});
// alert(room)
this.setState({ room: room });
} catch(err) {
alert(err);
}
}
updateIdentity(event) {
this.setState({
identity: event.target.value
});
}
returnToLobby() {
this.setState({ room: null });
}
removePlaceholderText() {
this.inputRef.current.placeholder = '';
}
render() {
const disabled = this.state.identity === '' ? true : false;
return (
<div className="app">
{
this.state.room === null
? <div className="lobby">
<input
ref={this.inputRef}
onClick={this.removePlaceholderText}
placeholder="What's your name?"
onChange={this.updateIdentity}
/>
<button disabled = {disabled} onClick={this.joinRoom}>Join Room</button>
</div>
: <Room returnToLobby={this.returnToLobby} room={this.state.room} />
}
</div>
);
}
}
export default App;
Room.jsx
import React, { Component } from 'react';
import Participant from './Participant';
const { connect } = require('twilio-video');
class Room extends Component {
componentDidMount() {
this.props.room.on('participantConnected', participant => this.addParticipant(participant));
this.props.room.on('participantDisconnected', participant => this.removeParticipant(participant));
window.addEventListener("beforeunload", this.leaveRoom);
}
componentWillUnmount() {
this.leaveRoom();
}
addParticipant(participant) {
console.log(`${participant.identity} has joined the room.`);
alert(`+ Participant : ${participant.identity}`)
this.setState({
remoteParticipants: [...this.state.remoteParticipants, participant]
})
}
removeParticipant(participant) {
alert(`Leaving : ${participant.identity}`)
console.log(`${participant.identity} has left the room`);
this.setState({
remoteParticipants: this.state.remoteParticipants.filter(p => p.identity !== participant.identity)
});
}
leaveRoom() {
this.props.room.disconnect();
this.props.returnToLobby();
}
constructor(props) {
super(props)
this.state = {
remoteParticipants: Array.from(this.props.room.participants.values())
}
this.leaveRoom = this.leaveRoom.bind(this);
}
render() {
return (
<div className="room">
<div className="participants">
<Participant
key={this.props.room.localParticipant.identity}
localParticipant="true"
participant={this.props.room.localParticipant} />
{
this.state.remoteParticipants.map(participant =>
<Participant key={participant.identity} participant={participant} />
)
}
</div>
<button id="leaveRoom" onClick={this.leaveRoom}>Leave Room</button>
</div>
);
}
}
export default Room
Participant.jsx
import React, { Component } from 'react';
import Track from './Track';
const { connect } = require('twilio-video');
class Participant extends Component {
componentDidMount() {
if (!this.props.localParticipant) {
this.props.participant.on('trackSubscribed', track => this.addTrack(track));
}
}
constructor(props) {
super(props);
const existingPublications = Array.from(this.props.participant.tracks.values());
const existingTracks = existingPublications.map(publication => publication.track);
const nonNullTracks = existingTracks.filter(track => track !== null)
this.state = {
tracks: nonNullTracks
}
}
addTrack(track) {
this.setState({
tracks: [...this.state.tracks, track]
});
}
render() {
return (
<div className="participant" id={this.props.participant.identity}>
<div className="identity">{this.props.participant.identity}</div>
{
this.state.tracks.map(track =>
<Track key={track} filter={this.state.filter} track={track}/>)
}
</div>
);
}
}
export default Participant
Track.jsx
import React, { Component } from 'react';
class Track extends Component {
componentDidMount() {
if (this.props.track !== null) {
const child = this.props.track.attach();
this.ref.current.classList.add(this.props.track.kind);
this.ref.current.appendChild(child)
}
}
constructor(props) {
super(props)
this.ref = React.createRef();
}
render() {
return (
<div className="track" ref={this.ref}>
</div>
)
}
}
export default Track
demo:https://android-anime.web.app
i have only two video events onJoin and onLeave do i need additional events ?
what is the solution? if your solution works i will award you best answer.Thanks !!

'delTodo' is not defined. React (line 51)

Error:
'delTodo' is not defined. React (line 51)
I am new to React. Here is the code; what did I do wrong?
import React, { Component } from 'react';
import Todos from './components/Todos';
import markComplete from './components/Todos'
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
todos: [
{
key: 1,
title: 'Take out the trash',
completed:false
},
{`enter code here`
key: 2,
title: 'Dinner with wife',
completed:true`enter code here`
},
{
key: 3,
title: 'Meeting with boss',
completed:false
}
]
}
}
asd = () =>{
}
// Toggle Complete
markComplete = (key) => {
this.setState({ todos: this.state.todos.map(todo=> {
if(todo.key === key) {
todo.completed = !todo.completed
}
return todo;
}) });
}
//Delete Todo
delTodo = (key) => {
console.log(key)
}
render() {
return (
<div className="App">
<Todos todos={this.state.todos} markComplete={markComplete}
delTodo={delTodo} />
</div>
);
}
}
export default App;
If you're using a class component, you need to use the this keyword when you refer to class attributes (state, methods, etc.). So the method should be this.delTodo:
return (
<div className="App">
<Todos
todos={this.state.todos}
markComplete={this.markComplete}
delTodo={this.delTodo}
/>
</div>
)

How to add props to state

I have a problem when trying to add my redux array to a component’s state:
componentDidMount() {
this.props.cardAction()
this.setState({ showCards: this.props.cardAction() })
}
hhhhhh undefined console log undefined
Here’s my dashboard code:
import React, { Component } from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import Header from '../../common/Header/'
import Masonry from '../../common/Masonry/'
import { cardAction } from '../../store/actions/Cards'
import Arrow_Down from '../../assets/img/arrow-down.svg'
class Dashboard extends Component {
componentDidMount() {
this.props.cardAction()
this.setState({ showCards: this.props.cardAction() })
}
constructor(props) {
super(props)
this.state = {
collapsed: true,
class: 'collapsed',
showCards: {},
}
this.toggleCollapse = this.toggleCollapse.bind(this);
}
toggleCollapse(i, info) {
console.log('i', info, 'iiiii', i)
this.setState({
collapsed: !this.state.collapsed,
class: this.state.collapsed ? '' : 'collapsed',
showCards: info
}, () => {
// my state is updated here !
console.log('cardsss', this.state.showCards)
})
if (this.state.showCards === 'active') {
let carddd = this.state.showCards
this.setState({
showCards: {
...this.state.showCards,
open: 'inactive'
}
});
}
else {
this.setState({
showCards: {
...this.state.showCards,
open: 'active'
}
});
}
}
render() {
console.log('hhhhhh', this.state.showCards)
const cardList = this.props.Cards.map((info, i) => {
return (
<div className={(info.open === 'active') ? 'collapsed' : ''} key={i}>
<div className={(info.open === 'active') ? 'header flex space-between active' : 'header flex space-between'}>
<h2>{info.title}</h2>
<span onClick={() => { this.toggleCollapse(i, info) }}><img src={Arrow_Down} alt='Arrow' /></span>
</div>
<div className='content'>
<p>{info.description}</p>
</div>
</div>
)
})
return (
<div>
<Header />
<Masonry columns={3} gap={20}>
{cardList}
</Masonry>
</div>
)
}
}
Dashboard.defaultProps = {
columns: 2,
gap: 20,
Cards: []
}
Dashboard.propTypes = {
Cards: PropTypes.array.isRequired,
}
const mapStateToProps = state => {
return { Cards: state.cards.result }
}
const mapDispatchToProps = dispatch => ({
cardAction: () => dispatch(cardAction())
})
export default connect(mapStateToProps, mapDispatchToProps)(Dashboard)
this.props.cardAction() is a redux action, it's not meant for you to directly assign to state, reason is redux action will return to reducer, not component. You should remove the setState in componentDidMount
componentDidMount() {
this.props.cardAction();
}
When you invoked this.props.cardAction(), it will call the function that defined in redux action file, and the result will be available at this.props.Cards as you mentioned above
const mapStateToProps = state => {
return { Cards: state.cards.result }
}

React setState called multiple times on the same state object

I have the following:
import React from 'react';
import ReactDOM from 'react-dom'
import {render} from 'react-dom';
import Forms from './forms/forms.jsx';
class Option1 extends React.Component {
render () {
return (
<p>Icon 1</p>
)
}
}
class TShirt extends React.Component {
render () {
console.log(this.props.currentState);
return <div className="thsirt">
<h1>{this.props.name}</h1>
<p>{this.props.iconID}</p>
{this.props.optionA ? <Option1 /> : ''}
</div>;
}
}
class Link extends React.Component {
render () {
return (
<li
data-id={this.props.el}
onClick={this.props.onClick}
className={this.props.activeClass}>{this.props.el}
</li>
);
}
}
class Nav extends React.Component {
getComponentID (id) {
switch(id) {
case 'name':
return 1;
break;
case 'color':
return 2;
break;
case 'design':
return 3;
break;
case 'share':
return 4;
break;
}
}
handleClick (event) {
// setting active class
var id = event.target.getAttribute("data-id");
this.props.action(id);
// switching coomponent based on active class
var component = this.getComponentID(id);
this.props.switchComponent(component);
}
render () {
var links = ['name', 'color', 'design', 'share'],
newLinks = [],
that = this;
links.forEach(function(el){
newLinks.push(<Link
onClick={that.handleClick.bind(that)}
activeClass={that.props.active == el ? 'active': ''}
key={el}
el={el}
/>
);
});
return (
<ol>
{newLinks}
</ol>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
color: '',
active: '',
formId: 1,
optionA: {
on: false,
icon_id: '',
option_id: '',
name: ''
}
};
this.setName = this.setName.bind(this);
this.setColor = this.setColor.bind(this);
this.setAtciveNavEl = this.setAtciveNavEl.bind(this);
this.setFormId = this.setFormId.bind(this);
this.setOptionA = this.setOptionA.bind(this);
this.setOptionAVisibility = this.setOptionAVisibility.bind(this);
}
setName (tshirt) {
this.setState({ name:tshirt })
}
setColor (color) {
this.setState({ color:color })
}
setAtciveNavEl (el) {
this.setState({ active:el })
}
setFormId (id) {
this.setState({ formId:id })
}
setOptionA (iconID, iconName) {
this.setState({
optionA:
{
icon_id: iconID,
name: iconName
}
})
}
setOptionAVisibility (onOff, optionID) {
this.setState({
optionA:
{
option_id: optionID,
on: onOff
}
})
}
render () {
return (
<section className={this.state.color}>
<Nav
active={this.state.active}
action={this.setAtciveNavEl}
switchComponent={this.setFormId}
/>
<TShirt
name={this.state.name}
icons={this.state.options}
optionA={this.state.optionA.on}
currentState={this.state}
/>
<Forms
name={this.state.name}
action={this.setName}
colorVal={this.setColor}
activeNav={this.setAtciveNavEl}
switchComponent={this.setFormId}
formID={this.state.formId}
setOptionA={this.setOptionA}
setOptionAVisibility={this.setOptionAVisibility}
/>
</section>
);
}
}
render(<App/>, document.getElementById('app'));
I need to populate this object at different times like this:
setOptionA (iconID, iconName) {
this.setState({
optionA:
{
icon_id: iconID,
name: iconName
}
})
}
setOptionAVisibility (onOff, optionID) {
this.setState({
optionA:
{
option_id: optionID,
on: onOff
}
})
}
The problem I have is taht when I console.log my state at:
class TShirt extends React.Component {
render () {
console.log(this.props.currentState);
return <div className="thsirt">
<h1>{this.props.name}</h1>
<p>{this.props.iconID}</p>
{this.props.optionA ? <Option1 /> : ''}
</div>;
}
}
after all my click events it seems like I loose the "on" and "option_id" from the optionA object.
Does calling setState on the same object override the previous setState?
If you are writing ES2015, you can use the spread operator to copy the whole object and just modify one of it's properties:
setOptionAVisibility (onOff, optionID) {
this.setState({
optionA:
{
...this.state.optionA,
option_id: optionID,
on: onOff
}
})
}
Can be very useful when modifying single properties of complex objects on the state tree.

Resources