How to properly write a React Class Component that can receive props? - javascript

I know how to receive props in presentational components but currently I need to also use functions which have logic therefore I'm needed to change my component into a Class Component right now, I don't know why I'm not able to receive the props.
Here is a part of my component:
class MemberInfoSubPage extends React.Component {
constructor(props) {
super(props);
this.state = {
};
this.renderRow = this.renderRow.bind(this);
}
As you can see, I'm using ES6 & I'm trying to render rows from a map but for now I'm just trying to receive props. Is this code provided correct? I mean the usual syntax.
PS: For additional info, I'm receiving 'props' is not defined. So yea, I'm not receiving the props after changing my component. Previously I was able to receive the props.
EDIT:
import React, {PropTypes} from 'react';
import ons from 'onsenui';
import * as Ons from 'react-onsenui';
class MemberInfoSubPage extends React.Component {
//const result = FlightApi.getAllFlightList();
constructor(props) {
super(props);
this.state = {
};
// this.stateToEntry = this.stateToEntry.bind(this);
this.renderRow = this.renderRow.bind(this);
}
renderRow(row,index) {
const x = 40 + Math.round(5 * (Math.random() - 0.5)),
y = 40 + Math.round(5 * (Math.random() - 0.5));
const names = ['Max', 'Chloe', 'Bella', 'Oliver', 'Tiger', 'Lucy', 'Shadow', 'Angel'];
const name = names[Math.floor(names.length * Math.random())];
return (
<Ons.ListItem key={index}>
<div className='left'>
<img src={`http://placekitten.com/g/${x}/${y}`} className='list__item__thumbnail' />
</div>
<div className='center'>
{name}
</div>
</Ons.ListItem>
);
}
render() {
if (props['index'] == 0) {
return (
<div className="memberInfoSubPage">
<div className="memberInfoSubPage-row1">
<span>{props['data-user'].id}</span>
<table border={1} className="memberInfoSubPage-Table">
<tr>
<th style={{color: 'grey'}}>Rank</th>
<th style={{color: 'grey'}}>Country</th>
</tr>
<tr>
<td>{props['data-user'].rank}</td>
<td>{props['data-user'].country}</td>
</tr>
</table>
</div>
<div>
<div className="memberInfoSubPage2-Summary-Title">Placement Performance Summary</div>
<table border={1} className="memberInfoSubPage-Table2">
<tr>
<td>L</td>
<td>R</td>
</tr>
<tr>
<td>{props['data-user'].placementPerformanceSummary.L}</td>
<td>{props['data-user'].placementPerformanceSummary.R}</td>
</tr>
</table>
</div>
<div>
<div className="memberInfoSubPage2-Summary-Title">Today Detail</div>
<table border={1} className="memberInfoSubPage-Table3">
<tr>
<td>L</td>
<td>R</td>
</tr>
<tr>
<td>{props['data-user'].todayDetail.L}</td>
<td>{props['data-user'].todayDetail.R}</td>
</tr>
</table>
</div>
<div> <table border={1} className="memberInfoSubPage-Table3">
<tr><th style={{color: 'grey'}}>Next Level Upgrade</th></tr>
<tr>
<td>{props['data-user'].nextLevelUpgrade}</td>
</tr>
</table>
</div>
<Ons.Button style={{margin: '6px'}}>Instant Upgrade</Ons.Button>
<div>
<div className="memberInfoSubPage2-Summary-Title" style={{color: 'grey'}}>Conversion Share Platform Portfolio</div>
<table border={1} className="memberInfoSubPage-Table3">
<tr style={{color: 'grey'}}>
<th>Market($)</th>
<th>Unit</th>
<th>Tradable Unit</th>
</tr>
<tr>
<td>{props['data-user'].market}</td>
<td>{props['data-user'].unit}</td>
<td>{props['data-user'].tradableUnit}</td>
</tr>
</table>
</div>
<div><table border={1} className="memberInfoSubPage-Table3">
<tr style={{color: 'grey'}}>
<th>Lock Units</th>
<th>Avg Price</th>
<th>Last Price</th>
</tr>
<tr>
<td>{props['data-user'].lockUnits}</td>
<td>{props['data-user'].avgPrice}</td>
<td>{props['data-user'].lastPrice}</td>
</tr>
</table>
</div>
</div>
);
}
else if (props['index'] == 1) {
return (
<Ons.List
dataSource={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]}
renderRow={this.renderRow}
renderHeader={() => <Ons.ListHeader>Summary</Ons.ListHeader>}/>
/*<div className="memberInfoSubPage2-Summary-Title">Summary</div>
<table className="memberInfoSubPage2-Summary-Table">
<tr><td>Credit</td><td>{props['data-user'].summary.credit}</td></tr>
<tr><td>Register</td><td>{props['data-user'].summary.register}</td></tr>
<tr><td>CP(S)</td><td>{props['data-user'].summary.cpS}</td></tr>
<tr><td>CP(0)</td><td>{props['data-user'].summary.cp0}</td></tr>
<tr><td>AP</td><td>{props['data-user'].summary.ap}</td></tr>
<tr><td>BO Point</td><td>{props['data-user'].summary.boPoint}</td></tr>
<tr><td>Listed Company Fund</td><td>{props['data-user'].summary.listedCompanyFund}</td></tr>
<tr><td>Promo</td><td>{props['data-user'].summary.promo}</td></tr>
<tr><td>TT</td><td>{props['data-user'].summary.tt}</td></tr>
<tr><td>Re-Entry Point</td><td>{props['data-user'].summary.reEntryPoint}</td></tr>
</table>*/
);
}
else {
return (
<p>Not receiving any index. No content can be shown.</p>
);
}
}
};
MemberInfoSubPage.propTypes = {
'data-pageName': PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
'defaultOption': PropTypes.string,
value: PropTypes.string,
'error': PropTypes.string,
'options': PropTypes.arrayOf(PropTypes.object)
};
export default MemberInfoSubPage;
Here is my code, I'm pretty sure I've missed something.
There is still a lot of unrefined code and the function renderRow & that Onsen list is copy pasted.

props is on the component instance, so you'll need to refer to it as this.props rather than just props in your render function.

Related

Why am I getting a TypeError when trying to run my code?

I'm trying to figure out why I'm getting Cannot destructure property 'id' of 'this.props.customer' as it is undefined. error. My code seems to be correct from the looks of it but despite this fact, I'm still getting the aforementioned error. Is there something minuscule that I'm overlooking?
Here's CustomerList.js file:
import React, { Component } from "react";
import Customer from "./Customer";
class CustomerList extends Component {
render() {
const customers = this.props.customers;
return(
<div className="data">
<table className="ui celled table">
<thead>
<tr>
<th style={{ width: '50px', textAlign: 'center' }}>#</th>
<th>Name</th>
<th>E-mail</th>
<th style={{ width: '148px' }}>Action</th>
</tr>
</thead>
<tbody>
{
customers.map(customer => {
return <Customer customer={customer} key={customer.id} />;
})
}
<Customer/>
</tbody>
</table>
</div>
);
}
}
export default CustomerList;
Here's Customer.js:
import React, { Component } from 'react';
class Customer extends Component {
render() {
const { id, first_name, last_name, email } = this.props.customer;
return (
<tr>
<td style={{ textAlign: 'center' }}>{id}</td>
<td>{`${first_name} ${last_name}`}</td>
<td>{email}</td>
<td>
<button className="mini ui blue button">Edit</button>
<button className="mini ui red button">Delete</button>
</td>
</tr>
);
}
}
export default Customer;
Below the map part you have a single
<Customer/>
This call to the Customer component has no parameters, so customer is undefined. That is why you get the error.

.map() function and deleting a row from a table with ReactJS

I'm having a problem wrapping my head around the .map() function as it relates to ReactJS. In practice, I have a table onto which I can add rows, but deleting a row by passing the index of the row is just not working. Here's what I have; can anyone clear up what I'm doing wrong?
import React from 'react';
import { render } from 'react-dom';
class CommentList extends React.Component {
constructor(props) {
super(props);
this.state = {
comments: []
};
this.handleCommentDelete = this.handleCommentDelete.bind(this);
}
handleCommentDelete(i) {
alert('i = ' + i);
let comments = [...this.state.comments];
comments.splice(i, 1);
this.setState({
comments: comments
});
}
render() {
return (
<table className="commentList">
<thead>
<tr>
<th>Name</th>
<th>Phone</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody>
{
this.props.data.map((comment, i) => {
return (
<tr className="comment" key={i}>
<td className="commentId">{comment.Id}</td>
<td className="commentName">{comment.Name}</td>
<td className="commentPhone">{comment.Phone}</td>
<td className="commentEmail">{comment.Email}</td>
<td className="commentCRUD">
<a onClick={(i) => this.handleCommentDelete(i)}>
<i className="fa fa-trash" />
</a>
</td>
</tr>
);
})
}
</tbody>
</table>
);
}
}
export default CommentList;
Thanks in advance!
You are passing the index i, not the right way. Also i would prefer to pass id rather than index. Here is how you can do that:
import React from 'react';
import { render } from 'react-dom';
class CommentList extends React.Component {
constructor(props) {
super(props);
this.state = {
comments: []
};
this.handleCommentDelete = this.handleCommentDelete.bind(this);
}
handleCommentDelete(id) {
let comments = this.state.comments.filter(comment => comment.id !== id);
this.setState({
comments: comments
});
}
render() {
return (
<table className="commentList">
<thead>
<tr>
<th>Name</th>
<th>Phone</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody>
{
this.props.data.map(comment => {
return (
<tr className="comment" key={comment.Id}>
<td className="commentId">{comment.Id}</td>
<td className="commentName">{comment.Name}</td>
<td className="commentPhone">{comment.Phone}</td>
<td className="commentEmail">{comment.Email}</td>
<td className="commentCRUD">
<a onClick={() => this.handleCommentDelete(comment.Id)}>
<i className="fa fa-trash" />
</a>
</td>
</tr>
);
})
}
</tbody>
</table>
);
}
}
export default CommentList;
Hope this works for you.

DataTable is show an error "No data available in table"

I had used DataTable component for my userlist to display the data stored in my database.
This is my global.js file
import React, { Component } from 'react';
import $ from 'jquery';
import DataTable from 'datatables.net';
function filterGlobal () {
$('#example').DataTable().search(
$('#global_filter').val()
).draw();
}
$(document).ready(function() {
$('#example').DataTable();
$('input.global_filter').on( 'keyup click', function () {
filterGlobal();
} );
} );
class Global extends React.Component {
constructor(props){
super(props);
this.state={
users:[],
isLoaded:false,
errorOnLoad:false
};
}
getuser(){
fetch('/api/users/getuser',{
method:'get'
})
.then((response)=>{
return response.json()
})
.then((data)=>{
this.setState({
users:data,
isLoaded:true,
err:{},
errorOnLoad:false,
});
this.getuser.bind();
})
.catch((err)=>{
this.setState({
err:err,
errorOnLoad:true
})
})
}
componentDidMount(){
this.getuser();
}
render() {
return (
<div>
<h2 className="contact-table">CONTACT LIST</h2>
<table>
<tbody>
<tr id="filter_global" style={{display: 'flex', justifyContent: 'flex-end'}}>
<td style={{width: '100px', alignSelf: 'center'}}>Global search</td>
<td align="center"><input type="text" className="global_filter" id="global_filter" style={{width: 'auto',border: '1px solid',marginBottom: '0px'}} /></td>
</tr>
</tbody>
</table>
<table id="example" className="display" style={{width: '100%'}}>
<thead>
<tr>
<th>Name</th>
<th>Email Address</th>
<th>Mobile Number</th>
<th>Message</th>
<th>Profile Photo</th>
</tr>
</thead>
<tbody>
{
this.state.users.map((user)=>(
<tr key={user.qid}>
<td>{user.name}</td>
<td>{user.emailAddress}</td>
<td>{user.mobileNumber}</td>
<td>{user.message}</td>
<td><img className="image-db" src={user.image} alt="" /></td>
</tr>
))
}
</tbody>
</table>
</div>
);
}
}
export default Global;
This is the displaying page when i open it. After refreshing the page or adding new data to the table error occuring.
When i am refreshing the page data Table is not working and displaying error.
But i am getting all the data & an error that No data available in table
Can anyone tell me what went wrong.
Thankyou.

ES6 React JS methods Calendar Component

I am creating a calendar component and at the moment can't work out why react won't render to the DOM the returned elements of my renderWeekDays method?
Currently I have the following:
export default class CalendarApp extends React.Component {
constructor() {
super();
// Bind Methods
this.renderWeekDays = this.renderWeekDays.bind(this);
}
renderWeekDays() {
return (
<tr><td>Render Week days Please</td></tr>
)
}
render() {
let overviewContent,
checkRates
// Add Check rates and availability section if Rooms page
if (this.props.roomPage) {
checkRates = (
<div>
<h2>Check rates and availability</h2>
<small>or call us on 0330 100 3180</small>
</div>
)
}
// Determine whether to show placeholder or actual dates
if (this.props.dateSelected) {
overviewContent = (
<div>
<span className="icon">Icon</span>
<span className="date-from">21 Jun</span>
<span className="seperate">-></span>
<span className="date-to">25 Jun</span>
<span className="clear">X</span>
</div>
)
} else {
overviewContent = (
<div>
<span className="icon">Icon</span>
<span className="check-in">Check-in</span>
<span className="seperate">-></span>
<span className="check-out">Check-out</span>
</div>
)
}
return (
<div className="calendar hotelroom-follow-calendar">
{ checkRates }
<div className="calendar-overview">
<button>
{ overviewContent }
</button>
</div>
<div className="calendar-container">
<div className="calendar-month">
<span className="previous">Prev</span>
June
<span className="next">Next</span>
</div>
<table className="calendar-table">
<thead>
<tr>
<td>M</td>
<td>T</td>
<td>W</td>
<td>T</td>
<td>F</td>
<td>S</td>
<td>S</td>
</tr>
</thead>
<tbody>
{ this.renderWeekDays }
</tbody>
</table>
</div>
{ Moment().format() }
</div>
)
}
I am not being presented with any errors, it simply won't load in <tr><td>Render Week days Please</td></tr>.
Any help would be much appreciated as I have double checked all bind() methods etc.
You need to actually invoke the function in your jsx.
<tbody>
{ this.renderWeekDays }
</tbody>
needs to be
<tbody>
{ this.renderWeekDays() }
</tbody>
and voila, it should work!

Communicating beteween parent and child with row ReactJs

I try to call a parent function from a child function.
I follow this example :Expose Component Functions but with this code my page does not load and my console is empty so i do not know find the problem.
I use webpack with babel and webpack-dev-server
Thank you for your answers.
I am sorry for my english.
class Row extends React.Component {
render(){
return(
<tr className="animated slideInRight">
<th scope="row">{this.props.data.ville_id}</th>
<td>{this.props.data.ville_nom}</td>
<td>{this.props.data.ville_nom_reel}</td>
<td>{this.props.data.ville_canton}</td>
<td><button className="btn btn-success" onClick={this.props.onClick} >Full Detail</button></td>
</tr>
)
}
}
export default class Metier extends React.Component {
constructor() {
super();
this.state = {
data: [],
};
}
deleteClick(e){
console.log("ici")
}
render(){
return(
<table className="table table-striped">
<thead>
<tr>
<th>IdVille</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{this.state.data.map(function(result,i){
var boundClick = this.deleteClick.bind(this,i)
return(
<Row onClick={boundClick} key={i} data={result} />
)
})}
</tbody>
</table>
)
}
}
You have to use the arrow function in the map so you can access this:
{this.state.data.map((result,i) => {
var boundClick = this.deleteClick.bind(this,i)
return(
<Row onClick={boundClick} key={i} data={result} />
)
})}
By using a simple function you create a new context and in that function you cannot access this.deleteClick. Using an arrow function you can still access it.

Categories