Meteor(REACT) -- Unable to update input text value - reactjs

Unable to change/update value of input which is coming from database. Tried to understand https://facebook.github.io/react/docs/forms.html but not getting it.
Basically code is about showing roles collection data in table format and update facility is in modal input field.
This is my UMRolesList.jsx
export default class UMRolesList extends TrackerReact(Component) {
rolesListData(){
return Meteor.roles.find({}).fetch();
}
constructor(){
super();
this.state = {
subscription : {
"rolesData" : Meteor.subscribe('rolefunction'),
}
}
}
render(){
return(
<section className="Content">
<div className="row reportWrapper">
<div className="col-md-10 col-lg-12 col-sm-12 col-xs-12 noLRPad">
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12 noLRPad">
<h1 className="reportTitleName">LIST OF ROLES</h1>
<hr/>
<UMaddRoles/>
<table className="table-responsive table table-striped table-hover myTable dataTable no-footer">
<thead className="table-head umtblhdr">
<tr className="hrTableHeader">
<th className="umHeader"> Role </th>
<th className="umHeader"> Action </th>
</tr>
</thead>
<tbody>
{ this.rolesListData().map( (rolesData)=>{
return <UMadd_role key={rolesData._id} roleDataVales={rolesData}/>
})
}
</tbody>
</table>
</div>
</div>
</div>
</section>
);
}
}
This is my UMadd_role.jsx
export default class UMadd_role extends TrackerReact(Component) {
handleChange(event){
console.log("changing the text area to: " + event.target.value)
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
constructor(props) {
super(props);
this.state = {
roleName: props.roleDataVales.name,
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
render(){
return(
<tr>
<td> {this.props.roleDataVales.name}</td>
<td>
<button className="editrole fa fa-pencil-square-o" data-toggle="modal" data-target={`#edit-${this.props.roleDataVales._id}`} ></button>
<div id={`edit-${this.props.roleDataVales._id}`} className="modal fade" role="dialog">
<div className="modal-dialog">
<div className="modal-content reportWrapper">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">×</button>
<h4 className="modal-title">Edit Role</h4>
</div>
<div className="modal-body col-lg-12 col-md-12 col-sm-12 col-xs-12">
<form className="editroles">
<div className="form-group col-lg-5 col-md-4 col-xs-12 col-sm-12 paddingLeftz">
<label>Role Name*</label>
<input type="text" ref="roleName" className="form-control rolesField" name={`${this.props.roleDataVales._id}-Namerole`} value=value={`${this.state.roleName}`} onChange={this.handleChange.bind(this)} required/>
</div>
<div className="form-group col-lg-1 col-md-4 col-xs-12 col-sm-12 ">
<label> </label>
<button type="button" onClick={this.editRole.bind(this)} id={this.props.roleDataVales._id} className="btn btn-primary submit" data-dismiss="modal">Edit Role</button>
</div>
</form>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-primary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</td>
</tr>
);
}
}
Thanks in advance!

The reason for that maybe because you have assigned this.props.roleDataVales.name and there is no onChange for the the input field.
Try storing the the value this.props.roleDataVales.name in the state in the constructor and have an onChange on input field to update the value.

Handle change event to change your value and setting it as a current state
handleChange(event){
this.setState({value: event.target.value});
}
In constructor, store your value which may be coming from database which is props.roleDataVales.name and save it in state which is (defined in constructor) {this.state.roleName}.
constructor(props) {
super(props);
this.state = {
roleName: props.roleDataVales.name,
};
this.handleChange = this.handleChange.bind(this);
}
And finally use defaultValue instead of value attribute and bind onChange event to input. Provide {this.state.roleName} to defaultValue which is coming from constructor.
<input type="text" ref="roleName" defaultValue={`${this.state.roleName}`} onChange={this.handleChange.bind(this)}/>

Related

Fetch data between two dates in React from Django API

I am trying to filter data between two dates and display it in a table. Currently, my table shows all the data from the database but I want the user to be able to select from that date to this date, and data between the specified dates to be displayed in the table.
My code:
import React from "react";
import APIHandler from "../utils/APIHandler";
import _ from "lodash";
import moment from "moment";
import DatePicker from "react-datepicker";
import { initiateGetTransactions } from "../components/Transactions";
import ReactHTMLTableToExcel from "react-html-table-to-excel";
class FarmerStatementComponent extends React.Component {
constructor(props) {
super(props);
console.log(props.match.params.id);
}
state = {
errorRes: false,
errorMessage: "",
btnMessage: 0,
sendData: false,
orders: [],
startDate: new Date(),
endDate: new Date(),
dataLoaded: false,
formSubmitted: false,
name: "",
id: "",
};
componentDidMount() {
this.fetchFarmerData().then(response => {
console.log(response.data);
this.setState({
orders: response.data
});
});
}
handleStartDateChange = (date) => {
this.setState({
startDate: date
});
}
handleEndDateChange = (date) => {
this.setState({
endDate: date
});
}
handleSubmit = (event) => {
debugger;
event.preventDefault();
const data = { startDate:this.state.startDate, endDate:this.state.endDate};
}
async fetchFarmerData() {
var apihandler = new APIHandler();
var farmerdata = await apihandler.fetchFarmerDetails(this.props.match.params.id);
console.log(farmerdata);
this.setState({ orders: farmerdata.data.data.orders });
this.setState({ name: farmerdata.data.data.name });
this.setState({ phone: farmerdata.data.data.phone });
this.setState({ dataLoaded: true });
}
print() {
window.print();
}
render() {
return (
<section className="content">
<div className="container-fluid">
<div className="block-header">
<h2>FARMER STATEMENT</h2>
</div>
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div className="card">
<div className="header">
<h2>
{this.state.name}'S STATEMENT
</h2>
<div className="header-dropdown m-r--5">
<h2>
{this.state.id}
</h2>
</div>
</div>
<div className="body">
<div className="table-responsive">
<div id="DataTables_Table_1_wrapper" className="dataTables_wrapper form-inline dt-bootstrap">
<div className="dt-buttons">
<a className="dt-button buttons-csv buttons-html5" tabIndex="0" aria-controls="DataTables_Table_1" href="#">
<span>
<ReactHTMLTableToExcel
className="btn btn-success"
tabIndex="0"
aria-controls="DataTables_Table_1"
table="DataTables_Table_1"
filename="FarmerStatement"
sheet="Sheet"
buttonText="Excel"
/>
</span>
</a>
<a className="dt-button buttons-print" tabIndex="0" aria-controls="DataTables_Table_1" href="#" onClick={this.print}>
<span onClick={() => this.print()}>Print</span>
</a>
<br/>
<form onSubmit={this.handleSubmit}>
<button type="submit" className="btn btn-info" >
Generate Report
</button>
</form>
</div>
<div id="DataTables_Table_1_filter" className="dataTables_filter">
<form onSubmit={this.handleSubmit}>
<label>
<i className="material-icons">date_range</i>Start Date:
<DatePicker
selected={this.state.startDate}
className="form-control datepicker"
name="Start Date: 30/07/2022"
aria-controls="DataTables_Table_1"
value={this.state.startDate}
onChange={this.handleStartDateChange}
/>
</label>
<br/>
<label>
<i className="material-icons">date_range</i>End Date:
<DatePicker
selected={this.state.endDate}
className="form-control datepicker"
name="End Date: 30/07/2022"
aria-controls="DataTables_Table_1"
value={this.state.endDate}
onChange={this.handleEndDateChange}
/>
</label>
</form>
</div>
{this.state.dataLoaded === false ? (
<div className="text-center">
<div className="preloader pl-size-xl">
<div className="spinner-layer">
<div className="circle-clipper left">
<div className="circle"></div>
</div>
<div className="circle-clipper right">
<div className="circle"></div>
</div>
</div>
</div>
</div>
) : ""}
<table className="table table-bordered table-striped table-hover dataTable js-exportable" id="DataTables_Table_1" role="grid" aria-describedby="DataTables_Table_1_info">
<thead>
<tr role="row">
<th className="sorting_asc" tabIndex="0" aria-controls="DataTables_Table_1" rowSpan="1" colSpan="1" aria-sort="ascending" aria-label="Name: activate to sort column descending" style={{width: "40px"}}>
#ORDER NO
</th>
<th className="sorting" tabIndex="0" aria-controls="DataTables_Table_1" rowSpan="1" colSpan="1" aria-label="Position: activate to sort column ascending" style={{width: "150px"}}>
CUSTOMER NAME
</th>
<th className="sorting" tabIndex="0" aria-controls="DataTables_Table_1" rowSpan="1" colSpan="1" aria-label="Office: activate to sort column ascending" style={{width: "101px"}}>
KILOS
</th>
<th className="sorting" tabIndex="0" aria-controls="DataTables_Table_1" rowSpan="1" colSpan="1" aria-label="Age: activate to sort column ascending" style={{width: "100px"}}>
PRICE PER KG
</th>
<th className="sorting" tabIndex="0" aria-controls="DataTables_Table_1" rowSpan="1" colSpan="1" aria-label="Start date: activate to sort column ascending" style={{width: "115px"}}>
ORDERED ON
</th>
</tr>
</thead>
<tbody>
{this.state.orders.map((farmer) => (
<tr role="row" className="odd" key={farmer.id}>
<td className="sorting_1">{farmer.id}</td>
<td className="sorting_1">{farmer.customer.name}</td>
<td className="sorting_1">{farmer.kgs}</td>
<td className="sorting_1">{farmer.price}</td>
<td className="sorting_1">{new Date(farmer.added_on).toLocaleString()}</td>
</tr>
))}
</tbody>
</table>
<div className="dataTables_info" id="DataTables_Table_1_info" role="status" aria-live="polite">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
}
export default FarmerStatementComponent;
You can add filter in query or you can do filter to incoming data from database before passing to table

I create a todo list system and I use a map to make a loop for all the items I have. But items are stuck for me in the same row in the table

I create a todo list system and I use a map to make a loop for all the items I have.
But items are stuck for me in the same row in the table.
This is a system I used to build in js vanila and now for practice I run it in react.
I would be happy for a solution.
In js vanila I would use insertAdjacentHTML
But I'm looking for the solution in react
demo for the app: https://v1-todolist.netlify.app
My Problem All items in one row.
I need not all items to be on the same line I need it to be dropped line like here
Example of how the item should look properly.
This system I built it in js vanila
if i add Div it not work
It does not sit well in the table and I also get a validateDOMNesting (...) error: cannot appear as a child of .
my code App.js
import { useState } from "react";
import "./App.css";
import Form from "./Form";
import Alert from "./Alert";
function App() {
const [nameTask, setNameTask] = useState("");
const [priority, setPriority] = useState("Low");
const [list, setList] = useState([]);
const [alert, setAlert] = useState({ show: false, type: "", msg: "" });
const handlerSubmit = function (e) {
e.preventDefault();
if (!nameTask) return showAlert(true, "danger", "you cannot input empty");
const newList = {
id: new Date().getTime().toString(),
title: nameTask,
priority: priority,
};
setList([...list, newList]);
};
const showAlert = function (show = false, type, msg) {
setAlert({ show, type, msg });
};
return (
<article className="vh-100 gradient-custom-2">
{alert.show && <Alert {...alert} showAlert={showAlert} />}
<Form
list={list}
setNameTask={setNameTask}
setPriority={setPriority}
handlerSubmit={handlerSubmit}
/>
</article>
);
}
export default App;
Form.js
import React from "react";
const Form = function ({ handlerSubmit, setNameTask, setPriority, list }) {
return (
<div className="container py-5 h-100">
<div className="row d-flex justify-content-center align-items-center h-100">
<div className="col-md-12 col-xl-10">
<div className="card mask-custom">
<div className="card-body p-4 text-white">
<div className="text-center pt-3 pb-2">
<img
src="https://mdbootstrap.com/img/Photos/new-templates/bootstrap-todo-list/check1.png"
alt="Check"
width="60"
/>
<h2 className="my-4">Task List</h2>
</div>
<form className="form-task" onSubmit={(e) => handlerSubmit(e)}>
<div className="col-auto">
<input
name="name-task"
type="text"
className="form-control task-input"
id="autoSizingInput"
placeholder="Add Task"
onChange={(e) => setNameTask(e.target.value)}
/>
</div>
<select
className="form-select"
aria-label="Default select example"
onChange={(e) => setPriority(e.target.value)}
>
<option value="Low">Low</option>
<option value="Normal">Normal</option>
<option value="High">High</option>
</select>
<button type="submit" className="btn btn-primary">
submit
</button>
</form>
<table className="table text-white mb-0">
<thead>
<tr>
<th scope="col">Task</th>
<th scope="col">Priority</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr className="fw-normal">
{list.map((item, index) => {
return (
<React.Fragment key={index}>
<th>
<span className="ms-2" data-name={`${item.title}`}>
{item.title}
</span>
</th>
<td className="align-middle priority-class">
<span className="badge ${value.color}">
{item.priority}
</span>
</td>
<td className="align-middle">
<h6 className="mb-0" data-id="${value.id}">
<a className="remove-link" href="#">
<span className="badge bg-gradient remove">
❌
</span>
</a>
<a className="complete-link" href="#">
<span className="badge bg-gradient complete">
✔
</span>
</a>
</h6>
</td>
</React.Fragment>
);
})}
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
);
};
export default Form;
Check this CodeSandbox
I was able to solve your issu just by adding a flex propriety to the panel that contain your list and by changing React.fragment by a div.
However it would perhaps be better to swap the node with the class fw-normal to a div and change the React.fragment to the node tr.

How to close bootstrap modal after submit form in React JS?

I have User.js file to submit form and I am trying to submit form using bootstrap modal. I have no problem to submit data into database.
But I have a problem to close bootstrap modal after I trigger onSubmit={createUser}.
I add onClick={handleCloseModal} and set it into false after I clicked on submit button.
But bootstrap modal isn't close. I don't have any idea what I am doing.
Here's my code in User.js.
import axios from 'axios';
import { data } from 'jquery';
import React, { useEffect, useState } from 'react';
import { Redirect, Link } from 'react-router-dom';
const Users = () => {
const [users, setUsers] = useState([]);
const [name, setName] = useState('');
const [closeModal, setCloseModal] = useState(false);
function handleCloseModal(){
document.getElementById("myModal").classList.remove("show", "d-block", "modal-open");
document.getElementsByClassName("modal-backdrop")[0].classList.remove("modal-backdrop");
}
useEffect( () => {
(
async () => {
const {data} = await axios.get('getUsers');
setUsers(data);
}
)()
}, []);
// Add
const createUser = async (e) => {
e.preventDefault();
await axios.post('createUser', {
name : name
}).then(
async () => {
const {data} = await axios.get('getUsers');
setUsers(data);
}
);
setCloseModal(true);
}
// Add
return(
<>
{/* Page Content */}
<div className="container-fluid">
<div className="row">
<div className="col-lg-12 col-md-12">
<div className="row">
<div className="col-lg-12">
<div className="card card-outline-info">
<div className="card-header">
<h4 className="m-b-0 text-white">Users</h4>
</div>
<div className="card-body">
{/* Modal */}
{!closeModal &&
<div id="myModal" className="modal bs-example-modal-lg" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true" style={{display: 'none', overflowY: 'auto'}}>
<div className="modal-dialog modal-lg">
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title" id="myModalLabel">Fields <font color="red">*</font> asterisk required</h4>
<button type="button" className="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div className="modal-body">
<form className="" id="" action="" onSubmit={createUser}>
<div className="col-md-12">
<div className="form-group row">
<label className="control-label text-right col-md-3"><font color="red">*</font> Name</label>
<div className="col-md-9">
<input type="text" id="name" className="form-control name" name='name' placeholder=""
onChange={e=>setName(e.target.value)}
/>
<small className="form-control-feedback"></small>
</div>
</div>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-info waves-effect" data-dismiss="modal">Close</button>
<button type="submit" className="btn btn-success waves-effect text-left" id="" onClick={handleCloseModal}>Create</button>
</div>
</form>
</div>
</div>
</div>
</div>
}
{/* Modal */}
{/* Content Layout Here */}
<button type="button" data-toggle="modal" data-target="#myModal" className="btn btn-xs btn-success">Add User</button>
<div className="table-responsive">
<table id="table-user">
<thead>
<tr>
<th style={{verticalAlign: 'top'}}>No</th>
<th style={{verticalAlign: 'top'}}>Name</th>
</tr>
</thead>
<tbody>
{users.map((user) => {
return(
<tr key={user.id}>
<td>{user.name}</td>
</tr>
)
})}
</tbody>
</table>
</div>
{/* Content Layout Here */}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{/* Page Content */}
</>
);
}
export default Users;
UPDATE :
Before I submit
After I submit
Am I missing something here ?
Appreciate someone can help me on this issue.
Many thanks.
Try this:
function handleCloseModal(){
document.getElementById("myModal").classList.remove("show");
}
For Bootstrap 4 try this:
function handleCloseModal(){
document.getElementById("myModal").classList.remove("show", "d-block");
}
EDIT
To remove the grey background after the closing of modal, you can do this:
function handleCloseModal(){
document.getElementById("myModal").classList.remove("show", "d-block");
document.querySelectorAll(".modal-backdrop")
.forEach(el => el.classList.remove("modal-backdrop"));
}
You can use data-dismiss="modal" to close Modal as Close Button
If you want use state closeModal, you can do add like this:
{!closeModal && <div id="myModal">{/* ... */}</div>}

react-redux how to access data globally from other containers that are not children

I am not sure how to do this, i understand how to store data in components but when creating containers etc it gets confusing as they need to be rendered but i just want to store data. online official docs are not very clear.
I would like to store the data in setstate globally so i can access it from any component. this will be related to all user information. so i can import User state and then say user.isGuest etc.
I currently do the the following in my header file but i need to expose the user data to any component without doing callbacks and passing data back to App.
import React, { Component } from 'react';
import {getHttpRequestJSON} from '../components/HTTP.js'
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { fetchActiveUser } from '../actions/index';
import { bindActionCreators } from 'redux';
class Header extends Component {
constructor(props){
super(props);
this.state = {
loading: true,
version: ''
};
}
initData = () => {
let self = this;
getHttpRequestJSON('/api/user/get/user/method/is/guest/format/json?quiet=1')
.then((response) => {
let isGuest = response.body.recordset.record.isGuest;
if(isGuest){
/*$(".logo").trigger('click');
//$("#overlay").show();
$('#modalIntro').modal('toggle');
$("#modalIntro").on("hidden.bs.modal", function () {
$(".logo").trigger('click');
});*/
}
self.props.activeUser.isGuest = isGuest;
self.setState({
loading : false,
version : response.header.version
});
})
.catch(error => {
console.log("Failed!", error);
//$('#myModalError .modal-body').html(error);
//$('#myModalError').modal('show');
});
}
componentDidMount() {
this.props.fetchActiveUser();
this.initData();
}
render() {
if(this.state.loading){
return (
<div className="container-fluid" id="top_section">
<div id="flash_alert" className="row" style={{margin:"0 auto"}} >
<div className="alert alert-success col-xs-3 col-sm-6 col-lg-3 text-center">
<strong>Success!</strong>
</div>
<div className="alert alert-info col-xs-3 col-sm-6 col-lg-3 text-center">
<strong>Info!</strong>
</div>
<div className="alert alert-warning col-xs-3 col-sm-6 col-lg-3 text-center">
<strong>Warning!</strong>
</div>
<div className="alert alert-danger col-xs-3 col-sm-6 col-lg-3 text-center">
<strong>Danger!</strong>
</div>
</div>
<div className="logo">
</div>
<div className="row-fluid">
<div className="header">
<div className="row-fluid">
<div className="col-xs-5 col-sm-7 col-md-9">
<h2 style={{paddingLeft: "15px !important"}} className="ellipsis">Home</h2>
</div>
<div className="col-xs-4 col-sm-3 col-md-2 vcenter hidden-print" style={{textAlign: "right",fontSize: "8pt",bottom: "-28px",position: "relative",float: "right"}}>
<span className="username"></span> | <Link className="logout" to={`/logout`}> Logout <img src="/images/page-layout/logout-button.gif" alt="Icon: Logout" title="Logout" /> </Link>
</div>
</div>
</div>
<div className="row-fluid" style={{clear: "both",position: "relative",top: "-50px",marginLeft: "95px"}}>
<div className="col-sm-8"> </div>
<div className="col-sm-4 text-right">
<Link to={`/home`}> Connectivity Compliance Portal (CCP) <span style={{fontSize:"7pt"}}></span> </Link>
</div>
</div>
</div>
<div id="myModalError" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header alert alert-danger">
<button type="button" class="close" data-dismiss="modal">x</button>
<h4 class="modal-title">Error</h4>
</div>
<div class="modal-body">
Unexpected error occured
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" data-dismiss="modal">Ok</button>
</div>
</div>
</div>
</div>
</div>
);
}
return (
<div className="container-fluid" id="top_section">
<div id="flash_alert" className="row" style={{margin:"0 auto"}} >
<div className="alert alert-success col-xs-3 col-sm-6 col-lg-3 text-center">
<strong>Success!</strong>
</div>
<div className="alert alert-info col-xs-3 col-sm-6 col-lg-3 text-center">
<strong>Info!</strong>
</div>
<div className="alert alert-warning col-xs-3 col-sm-6 col-lg-3 text-center">
<strong>Warning!</strong>
</div>
<div className="alert alert-danger col-xs-3 col-sm-6 col-lg-3 text-center">
<strong>Danger!</strong>
</div>
</div>
<div className="logo">
</div>
<div className="row-fluid">
<div className="header">
<div className="row-fluid">
<div className="col-xs-5 col-sm-7 col-md-9">
<h2 style={{paddingLeft: "15px !important"}} className="ellipsis">Home</h2>
</div>
<div className="col-xs-4 col-sm-3 col-md-2 vcenter hidden-print" style={{textAlign: "right",fontSize: "8pt",bottom: "-28px",position: "relative",float: "right"}}>
<span className="username">{this.props.activeUser.name}{` `}</span> | <Link className="logout" to={`/logout`}> Logout <img src="/images/page-layout/logout-button.gif" alt="Icon: Logout" title="Logout" /> </Link>
</div>
</div>
</div>
<div className="row-fluid" style={{clear: "both",position: "relative",top: "-50px",marginLeft: "95px"}}>
<div className="col-sm-8">
</div>
<div className="col-sm-4 text-right">
<Link to={`/home`}>Connectivity Compliance Portal (CCP)<span style={{fontSize:"7pt"}}>{` `}v{` `}{this.state.version}</span></Link>
</div>
</div>
</div>
<div id="myModalError" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header alert alert-danger">
<button type="button" class="close" data-dismiss="modal">x</button>
<h4 class="modal-title">Error</h4>
</div>
<div class="modal-body">
Unexpected error occured
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" data-dismiss="modal">Ok</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
function mapStateToProps(state) {
// Whatever is returned will show up as props
// inside of the component
return {
activeUser: state.activeUser
};
}
// Anything returned from this function will end up as props
// on this container
function mapDispatchToProps(dispatch){
// Whenever getUser is called, the result should be passed
// to all our reducers
return bindActionCreators({ fetchActiveUser }, dispatch);
}
//Promote component to a container - it needs to know
//about this new dispatch method, fetchActiveUser. Make it available
//as a prop
export default connect(mapStateToProps, mapDispatchToProps)(Header);
I have another container which i would like to access the data of fetchActiveUser.
import _ from 'lodash';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchContents } from '../actions';
import { Link } from 'react-router-dom';
import { fetchActiveUser } from '../actions/index';
import { bindActionCreators } from 'redux';
class HomeContent extends Component {
componentDidMount() {
this.props.fetchContents();
}
htmlDecode(input){
let e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
renderContent(classname) {
return _.map(this.props.content, c => {
if(c.target == classname){
return (
<div dangerouslySetInnerHTML={{ __html: c.content}} />
);
}
});
}
render() {
console.log(this.props);
return (
<div className="container-fluid">
<div className="row-fluid text-center" >
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">INTRODUCTION</h3>
</div>
<div className="panel-body panel_introduction">{this.renderContent('panel_introduction')}</div>
</div>
</div>
<div className="row-fluid text-center top-buffer">
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">Whats New!</h3>
</div>
<div className="panel-body panel_whats_new">{this.renderContent('panel_whats_new')}</div>
</div>
</div>
<div className="row-fluid text-center top-buffer">
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">DISCLAIMER</h3>
</div>
<div className="panel-body panel_disclaimer">{this.renderContent('panel_disclaimer')}</div>
</div>
</div>
<div className="modal fade bs-example-modal-lg" id="modalIntro" tabIndex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
<div className="modal-dialog modal-lg" role="document">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 className="modal-title" id="myModalLabel">Welcome to the Connectivity Compliance Portal (CCP)</h4>
</div>
<div className="modal-body">
You are receiving this message as you are a guest and require elevated privileges to make best use of the service. In order to do this you'll need to:
<ol start="1">
<li>Go to <a target="_blank" href="https://iam.domain.com/identity" target="_blank" >WIAM (https://iam.domain.com/identity)</a></li>
<li>Click on <i>"Request Access"</i> at the top</li>
<li>Search for <i>"CCP"</i></li>
<li>Select the relevant group and add it to the cart</li>
<li>Check Out!</li>
</ol>
<p>You can confirm if you have been added to the group by going to <Link to={`/ldapuser`}>https://ccp.domain.com/ldapuser</Link>. Once you see you have been added to the group log out of CCP and log back in and you should have the correct permissions. The process can take a few hours to a couple of days depending on how long the approvers take.</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return { content: state.content }
}
//Anything returned from this function will end up as props
//on this container
function mapDispatchToProps(dispatch){
// Whenever getUser is called, the result should be passed
// to all our reducers
return bindActionCreators({ fetchContents, fetchActiveUser }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(HomeContent);
React component state and redux state are two different things. The state from redux is a global state instance, and you connect parts of this state to your React components using the connect hoc.
So if you want to share user state between two components, you simply connect those two components with the same redux state selectors.
The result of the redux state selector will be passed as props to your react component. (hence the name mapStateToProps commonly used to map redux state to your component props).
After your fetch, you can trigger an action using the dispatch function of react-redux.
dispatch({
type: 'DATA_RECEIVED',
payload: {
source:<your source>,
data: <the data>,
}
})
Then create a reducer and add it to your root reducer:
export default (state ={}, action) => {
switch(action.type){
case 'DATA_RECEIVED':
return {
...state,
[action.payload.source]: {
...state[action.payload.source],
...data
}
}
default: return state;
}
}
Then select the state in your component:
connect((state,props)=> state.yourReducerLocation[props.resource])(YourComponent)
This uses the props arg to connect, so you can specify resource on YourComponent.
A couple of things:
you should create your actions using const values and actionCreators (functions emitting an action)
you should think about how your reducer will store the state retrieved
for selecting data you should use a mapStateToProps function
dispatch is automatically added when using connect with only a state selector, but it's better to add a dispatchToProps object method to automatically wrap your actionCreators with a dispatch function
For efficient selectors you should use reselect
For side-effects (i.e. loading async data) use a side-effect middleware, something like 'redux-saga'.

React button onClick not functioning properly

can you help me understand why this onClick event does not bind to the button and won't fire?
class DateSlider extends React.Component{
constructor(props){
super(props);
this.state = {
allValues: this.props.allValues,
}
this.onClick = this.onClick.bind(this);
}
onClick(){
console.log('here');
// this.props.change(event.target.text);
}
render(){
return (
<div class="date-slider col-xl-4 col-12">
<div class="row">
<div class="date-input-description col-xl-12 col-12">{this.props.unit}</div>
<div class="col-xl-12 date-picker-container">
<div class="col-xl-12">
<div class="row" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<div class="date-range col-xl-9 col-9">{this.props.initialValue}</div>
<div class="col-xl-3 col-9 date-picker-small-button">
<img class="mx-auto d-block" src="./images/small-arrow-down.svg" />
</div>
<div class="dropdown-menu dropdown-menu-right">
{
//HERE
this.state.allValues.map((value) => {
return <button key={value} class="dropdown-item" type="button" onClick={this.onClick}>{value}</button>
})
}
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
When clicking on the item that is rendered, it won't console.log anything.
this.state.allValues.map((value) => {
return <button key={value} class="dropdown-item" type="button" onClick={this.onClick}>{value}</button>})
should be
this.state.allValues.map((value) => {
return <button key={value} className="dropdown-item" type="button" onClick={this.onClick}>{value}</button>})
In other words: replace the class attribute with className.

Resources