React state updating but not showing while render - reactjs

I'm studying about react, I've made a form to save data with react,
I want to update the table again as data is saved, I've used setState for this purpose, The issue is state updating but not rendering, I've tried some ways to find the issue,
by using console.log() it is found that the state is properly changing
render function is properly working after changing state
here's my code
import React, { Component } from "react";
import Header from "../header";
import Table from "./table";
import Addbox from "./create__box";
import $ from "jquery";
import { Api__url } from "../../vars";
class index extends Component {
constructor(props) {
super(props);
// binding functions
this.getData = this.getData.bind(this);
this.table = this.table.bind(this);
this.show_create_box = this.show_create_box.bind(this);
// using state
this.state = {
data: "Fetching Records....",
create_box: "",
};
}
getData() {
$.ajax({
type: "POST",
url: `${Api__url}services/get`,
dataType: "JSON",
success: this.table,
});
}
table(d) {
this.setState({ data: <Table data={d} /> });
}
show_create_box() {
this.setState({create_box: <Addbox top="15vh" again_get_data={this.getData}/>});
}
componentDidMount() {
this.getData();
}
render() {
return (
<>
<Header />
<div className="container mt-5 px-5">
<div className="border__box p-2 col">
<div className="row m-0 px-3">
<div className="col">
<h2>Services in home page</h2>
</div>
<div className="col d-flex justify-content-end">
<button
onClick={this.show_create_box}
className="btn btn-outline-success show__create__box"
>
Add New Data
</button>
</div>
</div>
<div className="row m-0 py-2 px-4">{this.state.data}</div>
</div>
</div>
{this.state.create_box}
</>
);
}
}
export default index;
```
the code from the table file
```
import React, { Component } from "react";
import Updatebox from "./update__box";
class table extends Component {
constructor(props) {
super(props);
this.show_update_box = this.show_update_box.bind(this);
this.delete_record = this.delete_record.bind(this);
this.state = { update_box: "" };
// making data
this.tbody = props.data.map((d, index) => {
return (
<tr className="w-100 row m-0 p-0" id={d.services_id}>
<th className="col-1" scope="row">
{index + 1}
</th>
<td className="col-3">{d.services_name}</td>
<td className="col-4">{d.services_description}</td>
<td className="col-2">{d.services_icon}</td>
<td className="col-1">
<button
onClick={() => {
this.show_update_box(index);
}}
className="btn btn-outline-success"
>
Update
</button>
</td>
<td className="col-1">
<button
onClick={() => {
this.delete_record(index);
}}
className="btn btn-outline-danger"
>
Delete
</button>
</td>
</tr>
);
});
}
// Function to get close form instruction from another class
changeStuff(d) {
this.setState(d);
}
delete_record(id) {
alert(id);
}
show_update_box(key) {
this.setState({
update_box: (
<Updatebox
data={this.props.data[key]}
changeHandler={this.changeStuff.bind(this)}
/>
),
});
}
render() {
return (
<>
<table className="position-relative table table-hover ">
<thead className="table-dark">
<tr className="row m-0 p-0">
<th className="col-1">Sr #</th>
<th className="col-3">Name</th>
<th className="col-4">Description</th>
<th className="col-2">Icon</th>
<th className="col-1">Update</th>
<th className="col-1">Delete</th>
</tr>
</thead>
<tbody>{this.tbody}</tbody>
</table>
{this.state.update_box}
</>
);
}
}
export default table;
```
here's the code for creating the box
```
import React, { Component } from "react";
import CloseIcon from "#mui/icons-material/Close";
import $ from "jquery";
// import i from "./index";
export default class Addbox extends Component {
constructor(props) {
super(props);
this.data = { name: "", description: "", icon: "" };
this.state = this.data;
this.change = this.change.bind(this);
this.submit = this.submit.bind(this);
this.changeCSS = this.changeCSS.bind(this);
this.setCSS = this.setCSS.bind(this);
this.close_create_box = this.close_create_box.bind(this);
}
close_create_box() {
this.props.changeHandler({ create_box: "" });
}
change(e) {
var name = e.target.name;
var value = e.target.value;
this.setState({
[name]: value,
});
}
changeCSS() {
$("#create").removeClass("btn-outline-success");
$("#create").addClass("btn-outline-dark");
$("#create").prop("disabled", true);
$("#create").text("Sending....");
}
setCSS() {
$("#create").removeClass("btn-outline-dark");
$("#create").addClass("btn-outline-success");
$("#create").prop("disabled", false);
$("#create").text("Submit");
}
submit(e) {
e.preventDefault();
$.ajax({
type: "POST",
url: "http://127.0.0.1:8000/api/services/create",
data: this.state,
dataType: "JSON",
beforeSend: this.changeCSS,
success: (e) => {
alert(e.message);
this.props.again_get_data();
this.close_create_box();
},
error: (e) => {
this.setCSS();
alert(e.responseText);
},
});
}
render() {
return (
<form
onSubmit={this.submit}
className="add__box create__box"
method="POST"
style={{ top: this.props.top }}
>
<div className="mb-3 row">
<div className="col-10">
<h4>Add New Service</h4>
</div>
<div className="col-2">
<CloseIcon className="close" onClick={this.close_create_box} />
</div>
</div>
<div className="mb-3">
<label htmlFor="create_name" className="form-label">
Name
</label>
<input
id="create_name"
name="name"
type="text"
className="form-control"
onChange={this.change}
value={this.state.name}
required
minLength={10}
maxLength={100}
/>
</div>
<div className="mb-3">
<label htmlFor="create_desc" className="form-label">
Description
</label>
<textarea
id="create_desc"
className="form-control"
onChange={this.change}
required
value={this.state.description}
minLength={20}
name="description"
></textarea>
</div>
<div className="mb-3">
<label htmlFor="create_icon" className="form-label">
Icon
</label>
<input
id="create_icon"
type="text"
className="form-control"
onChange={this.change}
value={this.state.icon}
required
name="icon"
/>
</div>
<div className="m-5 row my-0">
<button id="create" type="submit" className="btn btn-outline-success">
Submit
</button>
</div>
</form>
);
}
}
```

as per react docs, UI components shouldn't be in state and it should only contain the minimal amount of data needed to represent your UI's state.
so instead of adding a UI element in the state, you should just add a minimal amount of data in it
Here's an example based on your code
constructor(props) {
...
this.state = {
status: "loading",
data: "Fetching Records....",
create_box: "",
};
}
table(d) {
this.setState({ data: d, status: "table" });
}
renderData() {
const d = this.state.data
const status = this.state.status
if (status == "loading") { return d }
if (status == "table") { return <Table data={d} /> }
}
render() {
return (
<>
...
<div className="row m-0 py-2 px-4">{renderData()}</div>
...
</>
);
}

Related

How to post an object in a react class component

Here is my CustomerBill.js
import React, { Component } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import axios from "axios";
import $ from "jquery";
import Box from "#mui/material/Box";
import Button from "#mui/material/Button";
import CustomerTable from "./table";
class CustomerBill extends Component {
constructor() {
super();
this.state = {
Customer: "",
customerTable: {
index: Math.random(),
id: "",
paymentDescription: "",
quantity: "",
unitPrice: "",
},
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange = (e) => {
if (
["id", "paymentDescription", "quantity", "unitPrice"].includes(
e.target.name
)
) {
let customerTable = { ...this.state.customerTable };
customerTable[e.target.dataset.id][e.target.name] = e.target.value;
} else {
this.setState({ [e.target.name]: e.target.value });
}
};
addNewRow = () => {
this.setState((prevState) => ({
customerTable: [
...prevState.taskList,
{
index: Math.random(),
id: "",
paymentDescription: "",
quantity: "",
unitPrice: "",
},
],
}));
};
clickOnDelete(record) {
this.setState({
customerTable: this.state.customerTable.filter((r) => r !== record),
});
}
handleSubmit(event) {
event.preventDefault();
const bill = {
Customer: this.state.customerTable,
};
axios
.post(`http://localhost:4000/customer/bill`, bill)
.then((response) => {
console.log(response.data);
return $(".alert-success").show();
});
this.setState({
Customer: "",
});
}
render() {
let { customerTable } = this.state;
return (
<div>
<div className="container">
<div className="form-div">
<h1>Customer Bill</h1>
<Box
component="form"
onSubmit={this.handleSubmit}
noValidate
sx={{ mt: 1 }}
onChange={this.handleChange}
>
<div className="row" style={{ marginTop: 20 }}>
<div className="col-sm-3"></div>
<div className="col-sm-12">
<div className="card">
<div className="card-header text-center">
Bill Description
</div>
<div className="card-body">
<div className="row">
<div className="col-sm-4"></div>
</div>
<table>
<thead>
<tr>
<th className="text-center"> sN </th>
<th className="text-center"> Id </th>
<th className="text-center">
Payment Description
</th>
<th className="text-center"> Quantity </th>
</tr>
</thead>
<tbody>
<CustomerTable
id="customerTable"
add={this.addNewRow.bind(this)}
delete={this.clickOnDelete.bind(this)}
customerTable={customerTable}
/>
</tbody>
</table>
</div>
</div>
</div>
<div className="col-sm-1"></div>
</div>
<Button type="submit" fullWidth sx={{ mt: 3, mb: 2 }}>
<span className="btn btn-warning btn-block form-control form-group">
Submit
</span>
</Button>
</Box>
</div>
</div>
</div>
);
}
}
export default CustomerBill;
Here is the table.js
import React from "react";
const CustomerTable = (props, val, idx, post) => {
return props.customerTable.map((val, idx, post) => {
let id = `id-${idx}`,
paymentDescription = `paymentDescription-${idx}`,
quantity = `quantity-${idx}`,
unitPrice = `unitPrice-${idx}`;
return (
<tr key={val.index}>
<td>
<input
type="text"
name="id"
data-id={idx}
id={id}
className="form-control "
/>
</td>
<td>
<input
type="text"
name="paymentDescription"
id={paymentDescription}
data-id={idx}
className="form-control "
/>
</td>
<td>
<input
type="text"
name="quantity"
id={quantity}
data-id={idx}
className="form-control"
/>
</td>
<td>
<input
type="text"
name="unitPrice"
id={unitPrice}
data-id={idx}
className="form-control"
/>
</td>
<td>
{idx === 0 ? (
<button
onClick={() => props.add()}
type="button"
className="btn btn-primary"
>
Add Row
</button>
) : (
<button
className="btn btn-danger"
onClick={() => props.delete(val)}
>
Delete Row
</button>
)}
</td>
</tr>
);
});
};
export default CustomerTable;
Am trying to post the customerTable object into Customer array. However, am getting Uncaught TypeError props.customerTable.map is not a function. How can i improve this code to be able to push the data to the customer array as an object. Thanks in advance
Your customerTable prop is initialized as an object, not an array so you can't use map on it.
You should initialize it this way:
customerTable: [{
index: Math.random(),
id: "",
paymentDescription: "",
quantity: "",
unitPrice: "",
}],
Try to use Object.values()
Check the example below:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values

How to validate a table with arrays using SimpleReactValidator

I have a table that can add and delete rows. However, am not able to validate the table. if the table cells are empty or filled am not able to post the values to the backend. The error message still shows.What is the best way to validate the table. I would like to have the error message show if the fields are empty on submit.
payment.js
import React, {Component } from "react";
import "bootstrap/dist/css/bootstrap.min.css"
import axios from "axios"
import SimpleReactValidator from "simple-react-validator"
import Box from '#mui/material/Box';
import Button from "#mui/material/Button";
import BillTable from "./billTable"
import $ from 'jquery'
class Payment extends Component {
constructor(){
super()
this.state = {
Bill:"",
billTable: [{
index: Math.random(),
serialNumber: "",
item:"",
cost:""}],
errorMessage: '',
}
this.validator = new SimpleReactValidator({autoForceUpdate: this,messages: {
default: 'Please enter this field!'
},element: message => <div style={{color: "red"}}>{message}</div>})
this.handleSubmit = this.handleSubmit.bind(this)
this.handleChange = this.handleChange.bind(this)
}
handleChange = (e) => {
if (["serialNumber", "item", "cost"].includes(e.target.name)) {
let billTable = [...this.state.billTable]
billTable[e.target.dataset.id][e.target.name] = e.target.value;
}
else {
this.setState({ [e.target.name]: e.target.value })
}
};
addNewRowPlan = () => {
this.setState((prevState) => ({
billTable: [...prevState.billTable, { index: Math.random(), serialNumber: "", item: "", cost:""}],
}));
}
deleteRow = (index) => {
this.setState({
billTable: this.state.billTable.filter((s, sindex) => index !== sindex),
});
}
clickOnDelete(record) {
this.setState({
billTable: this.state.billTable.filter(r => r !== record),
});
}
handleSubmit(event){
event.preventDefault()
if(this.validator.allValid()){
this.validator.hideMessages()
const billed = {
Bill:this.state.billTable
};
axios.post(`http://localhost:4000/bill`, billed,{
})
.then(response => {
console.log(response.data)
return $('.alert-success').show();
})
this.setState({
Bill:"",
})
}
else{
this.validator.showMessages()
this.forceUpdate()
return $('.alert-danger').show();
}
}
render() {
let {billTable} = this.state
return (
<div>
<div className="container">
<div className="form-div">
<h1>Billing</h1>
<Box component="form" onSubmit={this.handleSubmit} noValidate sx={{ mt: 1}} onChange={this.handleChange}>
<div className="row" style={{ marginTop: 20 }}>
<div className="col-sm-3"></div>
<div className="col-sm-12">
<div className="card">
<div className="card-header text-center">Bill</div>
<div className="card-body">
<div className="row">
<div className="col-sm-4">
</div>
</div>
<table>
<thead>
<tr>
<th>Serial #</th>
<th>Item</th>
<th>Cost</th>
</tr>
</thead>
<tbody>
<BillTable id="bill" add={this.addNewRowPlan.bind(this)} delete={this.clickOnDelete.bind(this)} billTable={billTable} />
{this.validator.message('bill',this.state.Bill,'required')}
</tbody>
</table>
</div>
</div>
</div>
<div className="col-sm-1"></div>
</div>
<Button
type="submit"
fullWidth
sx={{ mt: 3, mb: 2}}
>
<span>Submit</span>
</Button>
</Box>
</div>
</div>
</div>
);
}
}
export default Payment;
billTable.js
import React from "react"
const billTable = (props) => {
return (props.billTable.map((val, idx) => {
let serialNumber = `serialNumber-$${idx}`, item = `item-$${idx}`, cost = `cost-$${idx}`
return (
<tr key={val.index}>
<td>
<input type="text" name="serialNumber" data-id={idx} id={serialNumber} className="form-control" />
</td>
<td>
<input type="text" name="item" data-id={idx} id={item} className="form-control " />
</td>
<td>
<input type="text" name="cost" data-id={idx} id={cost} className="form-control"/>
</td>
<td>
{
idx===0?<button onClick={()=>props.add(idx)} type="button" className="btn btn-primary">Add Row</button>
: <button className="btn btn-danger" onClick={(() => props.delete(val))} >Delete Row</button>
}
</td>
</tr>
)
})
)
}
export default billTable
`````````````````````
How can i correct this code. Thank you in advance

In REACT When I try to update date using setState but it doesn't change date it always show current date but in console it shows the changed date

**import React, { Component } from 'react'
import moment from 'moment'
import {Form, Formik, Field, ErrorMessage} from 'formik'
import TodoDataService from '../../api/todo/TodoDataService'
import AuthenticationService from './AuthenticationService'
class TodoComponent extends Component {
constructor(props){
super(props)
this.state = {
id:this.props.params.id,
description:'',
targetDate: moment(new Date()).format('YYYY-MM-DD')
}
this.onSubmit = this.onSubmit.bind(this);
this.validate = this.validate.bind(this);
}
componentDidMount(){
let username = AuthenticationService.getLoginUserName()
TodoDataService.retrieveTodo(username, this.state.id)
.then(response => this.setState({
description: response.data.description,
targetDate: moment(response.data.targetDate).format('YYYY-MM-DD')
}))
}
validate(values){
let error = {}
if(!values.description){
error.description = "Enter a Description"
}
else if(values.description.length<5){
error.description = "Enter atleast 5 Characters in Description"
}
if(!moment(values.targetDate).isValid()){
error.targetDate="Enter a valid date"
}
return error
}
onSubmit(values){
let username = AuthenticationService.getLoginUserName()
let todo={
id: this.state.id,
description:values.description,
targetDate:values.targetDate
}
console.log(values)
if(this.state.id === -1){
TodoDataService.createTodo(username, todo)
.then(()=> this.props.navigate('/todos'))
}else{
TodoDataService.updateTodo(username, this.state.id,
todo).then(() => this.props.navigate('/todos'))
}
}
render() {
let {description, targetDate} = this.state;
return (
<div>
<h1>Update Todo Form </h1>
<div className="container">
<Formik initialValues = {{description, targetDate}} onSubmit={this.onSubmit}
validateOnChange={false} validateOnBlur={false} validate={this.validate} enableReinitialize={true}>
{
(props) =>(
<Form>
<ErrorMessage name="description" component="div" className="alert alert-warning"/>
<ErrorMessage name="targetDate" component="div" className="alert alert-warning"/>
<fieldset className="form-group">
<label>Description</label>
<Field className="form-control" type="text" name="description"/>
</fieldset>
<fieldset className="form-group">
<label>Target Date</label>
<Field className="form-control" type="date" name="targetDate"/>
</fieldset>
<button className="btn btn-success" type="submit" >Save</button>
</Form>
)
}
</Formik>
</div>
</div>
)
}
}
export default TodoComponent;**
import React, { Component } from 'react';
import TodoDataService from '../../api/todo/TodoDataService';
import AuthenticationService from './AuthenticationService';
import moment from 'moment';
class ListTodoComponent extends Component{
constructor(props){
super(props);
this.state={
todos:[],
message:null
}
this.deleteTodoClicked = this.deleteTodoClicked.bind(this);
this.refreshTodos = this.refreshTodos.bind(this);
this.updateTodoClicked = this.updateTodoClicked.bind(this);
this.addTobeClicked = this.addTobeClicked.bind(this);
}
componentDidMount(){
this.refreshTodos();
}
addTobeClicked(){
this.props.navigate(`/todos/-1`)
}
deleteTodoClicked(id){
let username = AuthenticationService.getLoginUserName()
TodoDataService.deleteTodo(username, id)
.then( response =>{
this.setState({message:`Delete of todo id ${id} Successfull`})
this.refreshTodos()
})
}
refreshTodos(){
let username = AuthenticationService.getLoginUserName()
TodoDataService.retrieveAllTodos(username)
.then(
response => {
this.setState({todos:response.data})
}
)
}
updateTodoClicked(id){
console.log("updated");
this.props.navigate(`/todos/${id}`)
}
render(){
return (
<div>
<div className="container">
<h1>List of Todos</h1>
{this.state.message &&<div className="alert alert-success">{this.state.message}</div>}
<table className="table">
<thead>
<tr>
<th>ID</th>
<th>Description</th>
<th>Is Completed?</th>
<th>Target Date</th>
<th>Delete</th>
<th>Update</th>
</tr>
</thead>
<tbody>
{
this.state.todos.map(
todo =>
<tr key={todo.id}>
<td>{todo.id}</td>
<td>{todo.description}</td>
<td>{String(todo.done)}</td>
<td>{moment(todo.targetDate).format('YYYY-MM-DD')}</td>
<td><button className="btn btn-warning" onClick={() => this.deleteTodoClicked(todo.id)}>Delete</button></td>
<td><button className="btn btn-success" onClick={() => this.updateTodoClicked(todo.id)}>Update</button></td>
</tr>
)
}
</tbody>
</table>
<div className="row">
<button className="btn btn-success" onClick={this.addTobeClicked}>Add Todo</button>
</div>
</div>
</div>
)
}
}
export default ListTodoComponent
When I try to add date but date remain same date but in console it shows the new added date why new added date don't show in screen.
When I try to add date but date remain same date but in console it shows the new added date why new added date don't show in screen.
When I try to add date but date remain same date but in console it shows the new added date why new added date don't show in screen.

How could I have a successful pop - up of dialog box?

My aim is to have my modal dialog box pop up on click. However, I receive this error every time I execute:
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
See fb.me/react-invalid-hook-call for tips about how to debug and fix this problem
May I have some direction on where I am going wrong with this?
import React from 'react';
import { connect } from 'react-redux';
import { myActions } from './actions/my.actions';
import { Modal, Button } from 'react-bootstrap';
class LoadTable extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
Search: "Search",
visible: false
}
this.doSearch = this.doSearch.bind(this);
this.handleShow = this.handleShow.bind(this);
this.handleClose = this.handleClose.bind(this);
this.runstuff = this.runstuff(this);
}
componentDidMount() {
this.props.getstuff()
.then((res) => {
this.setState({
data: res.results.response || [], <--IT shows in the error that it breaks here.
visible: false
})
});
}
doSearch(e) {
const { name, value } = e.target;
this.setState({ [name]: value });
console.log("Search");
}
handleShow() {
this.setState({ visible: true });
}
handleClose() {
this.setState({ visible: false });
}
runstuff() {
}
render() {
const { data, Search } = this.state;
return data.length > 0 ? (
<div className="row row-centered">
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12 col-centered">
<div id="Search" className="row col-xs-5 col-lg-2">
<div className="form-group">
<input className='form-control' type="text" placeholder="Search" name="Search" value={Search} onChange={this.doSearch} autoFocus />
</div>
</div>
<table className="table table-striped">
<thead>
<tr>
<td>Name</td>
<td>stuff</td>
<td>Start</td>
<td>End</td>
<td>Status</td>
<td></td>
<td></td>
</tr>
</thead>
<tbody>
{
data.map((dt) => {
return (
<tr>
<td>{dt.name}</td>
<td>{dt.stuff}</td>
<td>{dt.start}</td>
<td>{dt.end}</td>
{ dt.status ?
<td>
<div className="alert alert-success" role="alert"></div>
</td>
:
<td>
<div className="alert alert-danger" role="alert"></div>
</td>
}
<td><button type="button" className="btn btn-primary" onClick={this.runStuff}>Run Stufff</button></td>
<td><button type="button" className="btn btn-info" onClick={this.displayLog}><View Stuff</button></td>
<Modal
show={this.state.visible}
onHide={this.handleClose}
>
<Modal.Header closeButton>
<Modal.Title>Run Stuff for Stuff</Modal.Title>
</Modal.Header>
<Modal.Body>
<div>{dt.lotsofstuff}</div>
</Modal.Body>
<Modal.Footer>
<Button
variant="secondary"
onClick={this.handleClose}
>
Close
</Button>
<Button variant="primary" onClick={this.handleClose}>
Download
</Button>
</Modal.Footer>
</Modal>
</tr>
);
})
}
</tbody>
</table>
</div>
</div>
) :
<div className="row">
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<p>No Data to Display at the moment</p>
</div>
</div>;
}
}
function mapStateToProps(state) {
return {
};
}
const mapDispatchToProps = dispatch => ({
getstuff: () => dispatch(myActions.getstuff())
});
export default connect(mapStateToProps, mapDispatchToProps)(myLoad);

React and typescript using datepicker error cant find module

I was using React and Typescript. I installed react-datepicker and imported into my code. This error occurred:
module can't find react-datepicker
But I have react-datepicker module in node_module. why does the error occure?
I'm using TSX file method.
todo.component.tsx
import * as React from 'react';
import * as classNames from 'classnames';
import TodoList from './todo.list';
import { Todo } from './../todo.interface';
import { Button } from 'react-bootstrap';
import DatePicker from 'react-datepicker';
import moment from 'moment';
import 'react-datepicker/dist/react-datepicker.css';
const KEYCODE_ENTER = 13;
export default class TodoComponent extends React.Component
<TodoComponentProps, TodoComponentState> {
constructor(props) {
super(props);
this.state = {
description: '',
valid: true,
items: [], text: '',
startDate: '',
};
this.removeTodos = this.removeTodos.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(date) {
this.setState({
startDate: date
});
}
addTodos(e) {
e.preventDefault();
this.setState({
items: [this.state.text, ...this.state.items],
text: ''
});
}
removeTodos(name, i) {
let items = this.state.items.slice();
items.splice(i, 1);
this.setState({
items
});
}
updateValue(e) {
this.setState({ text: e.target.value })
}
openNav() {
document.getElementById("mySidenav").style.width = "250px";
console.log(this)
}
closeNav() {
document.getElementById("mySidenav").style.width = "0";
}
setDescription(event) {
this.setState({ valid: true, description: event.target.value });
}
addTodo(event) {
if (event && event.keyCode !== KEYCODE_ENTER && event.type !== 'click') {
return;
}
if (!this.state.description.length || this.state.description.length > 50) {
this.setState({ valid: false });
} else {
this.props.addTodo(this.state.description);
this.setState({ description: '' });
}
}
render() {
let inputClass = classNames('form-group', {
'has-error': !this.state.valid
});
return (
<div>
<div className="container" onKeyDown={this.addTodo.bind(this)}>
<div className="row">
<div className="col-sm-12">
<h2 className="text-center">What do you need to do?</h2>
<br />
<br />
</div>
<div className="col-sm-6 col-sm-offset-3">
<div className={inputClass}>
<label className="control-label">Task description</label>
<input className="form-control input-lg" type="text" value={this.state.description} onChange={this.setDescription.bind(this)} />
</div>
</div>
<div className="col-sm-3 col-sm-offset-3">
<button className="btn btn-success btn-block" onClick={this.addTodo.bind(this)}>
<i className="fa fa-plus"></i> Add Todo
</button>
</div>
<div className="col-sm-3">
<button className="btn btn-danger btn-block" onClick={this.props.removeDoneTodos.bind(this)}>
<i className="fa fa-trash-o"></i> Remove done todos
</button>
</div>
</div>
<br />
<br />
<div className="row">
<div className="col-sm-6 col-sm-offset-3" onClick={this.openNav.bind(this)}>
<TodoList {...this.props} />
</div>
</div>
<div id="mySidenav" className="row offcanvas">
<div className="sideNav">
<span onClick={this.closeNav.bind(this)}><i className="fa fa-lg fa-close"></i></span>
<br /><br />
<div className="due">
<DatePicker
inline
selected={this.state.startDate}
onChange={this.handleChange}
/>
</div>
<hr />
<div className="remind">
</div>
<hr />
<div className="sublist" >
<TodosubList items={this.state.items} removeTodos={this.removeTodos} />
<form onSubmit={(e) => this.addTodos(e)}>
<input
placeholder="Add SubTask"
value={this.state.text}
onChange={(e) => { this.updateValue(e) }}
/>
<button type="submit">+</button>
</form>
</div>
<hr />
<div className="description">
</div>
<hr />
<div className="comment">
</div>
<hr />
<div className="commentIn">
</div>
</div>
</div>
</div>
</div>
);
}
}
class TodosubList extends React.Component<{ items?: any; removeTodos: any; }, {}> {
removeItem(item, i) {
this.props.removeTodos(item, i);
}
render() {
return (
<ul className="sub">
{this.props.items.map((todo, i) => {
return <li onClick={() => { this.removeItem(todo, i) }} key={i}>{todo}</li>
})}
</ul>
);
}
}
interface TodoComponentProps {
todos: Todo[];
addTodo(description: string): void;
addTodos?: any;
toggleTodo: React.MouseEventHandler;
editTodo: React.MouseEventHandler;
removeTodo: React.MouseEventHandler;
removeDoneTodos: React.MouseEventHandler;
}
interface TodoComponentState {
description?: string;
subdescription?: any;
valid?: boolean;
items?: any;
text?: any;
startDate?: any;
}
cmd error:
error:cant find module react-datepicker.
I think you need to npm install #types/react-datepicker.

Resources