When the Click event is made on the button in the form section, I want to map the data in the initial state and move it to the ListGroupItem in the table part, but I could not succeed.
I don't know if it is related to this situation, but Uncaught TypeError: dispatch is not a function error.
FormSection.js
```
import React, { Component } from "react";
import { connect } from "react-redux";
import { Field, FormSection, reduxForm } from "redux-form";
import { withTranslation } from "react-i18next";
import { bindActionCreators } from "redux";
import { Button, ButtonToolbar } from "reactstrap";
import alertify from "alertifyjs";
import "alertifyjs/build/css/alertify.css";
import InputFormSection from "../../../../shared/components/generic-form/FormSections/InputSections/InputFormSection";
import renderSelectField from "../../../../shared/components/form/Select";
import { rules } from "../../../../shared/components/generic-form/validate";
import * as addHelpActions from '../actions/addHelpActions'
class HelpdeskReduxForm extends Component {
state = {
data: [
{ id: 1, issueName: "Ürün Kontrolu" },
{ id: 2, issueName: "Ürün Yerleştirme" },
{ id: 3, issueName: "Üretim Bandı Konrolu" },
{ id: 4, issueName: "Üretim Bandı " },
{ id: 5, issueName: "Üretim" },
{ id: 6, issueName: "Kurulum" },
{ id: 7, issueName: "Teknik" },
{ id: 8, issueName: "s" },
{ id: 9, issueName: "d" },
{ id: 10, issueName: "a" },
],
userName: "",
};
onChangeHandler = (event) => {
// this.setState({ userName: event.target.value });
let name = event.target.name;
let value = event.target.value;
this.setState({ [name]: value });
console.log(event);
};
onSubmitHandler = (event) => {
alertify.success("Talebiniz Başarıyla İletilmiştir.");
event.preventDefault();
};
addToHelp = (help) => {
this.props.actions.addToHelp({quantity:1 , help})
alertify.success(help.issueName + "Talebiniz Eklendi")
console.log(help);
help.preventDefault();
}
render() {
return (
<form className="form form--horizontal" onSubmit={this.onSubmitHandler}>
<FormSection>
<InputFormSection
onChange={this.addToHelp}
name="firstname"
label="İsim"
component="input"
props={{
type: "text",
placeholder: "İsim",
}}
/>
</FormSection>
<FormSection name="">
<InputFormSection
name="lastName"
label="Soyisim"
validate={["required_array"]}
props={{
type: "text",
placeholder: "Soyisim",
}}
/>
</FormSection>
<FormSection name="" validate="required">
<InputFormSection
name="email"
label="Email"
validate={["required"]}
props={{
type: "text",
placeholder: "Email",
}}
/>
</FormSection>
<div className="form__form-group">
<div className="form__form-group-field">
<Field
name="name"
component={renderSelectField}
options={
this.state.data &&
this.state.data.map((helpTopic) => {
return {
value: helpTopic.id,
label: helpTopic.issueName,
};
})
}
validate={rules["required"]} //Controller
/>
</div>
</div>
<div>
<ButtonToolbar className="form__button-toolbar">
<Button
onClick={() => this.addToHelp(this.help)}
color="primary"
size="lg"
type="submit"
disabled={this.props.pristine || this.props.submitting}
>
Gönder
</Button>
</ButtonToolbar>
</div>
</form>
);
}
}
function mapStateToProps(state){
return {
box: state.jobSaveReducer,
}
}
function mapDispatchToProps(dispatch) {
return {
actions: {
addToHelp: bindActionCreators(addHelpActions.addToHelp, dispatch)
},
};
}
HelpdeskReduxForm = reduxForm({
form: "New_Helpdesk_Form", // a unique identifier for this form
enableReinitialize: true,
})(HelpdeskReduxForm);
export default connect(
mapDispatchToProps, mapStateToProps
)(withTranslation("common")(HelpdeskReduxForm));
```
**saveReducer.js**
```
import * as actionTypes from '../actions/actionTypes'
import initialState from './initialState'
export default function jobSaveReducer(state = initialState.box, action){
switch (action.type) {
case actionTypes.ADD_TO_HELP:
var addedHelp = state.find(c => c.help.id === action.payload.help.id);
if(addedHelp){
var newState = state.map(helpTopic => {
if(helpTopic.help.id === action.helpTopic.help.id){
return Object.assign({},addedHelp,{quantity: addedHelp.quantity + 1})
}
return helpTopic;
})
return newState;
}else{
return [...state, {...action.payload}] // copy the state and add action payload ( redux ile push, pop yapılmaz)
}
default:
return state;
}
}
**TablePart.js**
```
import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import {
Button,
ButtonGroup,
UncontrolledTooltip,
Badge,
ListGroup,
ListGroupItem,
Label,
} from "reactstrap";
import { withTranslation } from "react-i18next";
import { withRouter } from "react-router-dom";
import MaterialTable from "material-table";
// Material Theme
import { MuiThemeProvider, createMuiTheme } from "@material-ui/core/styles";
//Material Icons
import Search from "@material-ui/icons/Search";
import ViewColumn from "@material-ui/icons/ViewColumn";
import SaveAlt from "@material-ui/icons/SaveAlt";
import ArrowUpward from "@material-ui/icons/ArrowUpward";
import ChevronLeft from "@material-ui/icons/ChevronLeft";
import ChevronRight from "@material-ui/icons/ChevronRight";
import FirstPage from "@material-ui/icons/FirstPage";
import LastPage from "@material-ui/icons/LastPage";
import Check from "@material-ui/icons/Check";
import FilterList from "@material-ui/icons/FilterList";
import Remove from "@material-ui/icons/Remove";
import DeleteOutline from "@material-ui/icons/DeleteOutline";
import Clear from "@material-ui/icons/Clear";
import { connect } from "react-redux";
import jobSaveReducer from "../../NewTicket/reducers/jobSaveReducer";
class Table extends PureComponent {
static propTypes = {
t: PropTypes.func.isRequired,
columns: PropTypes.array,
data: PropTypes.any,
actions: PropTypes.array,
isRemoteData: PropTypes.bool,
changePageorPageSize: PropTypes.func,
toolbar: PropTypes.bool,
paging: PropTypes.bool,
search: PropTypes.bool,
onRowClick: PropTypes.func,
onRowClickSelection: PropTypes.bool,
selection: PropTypes.bool,
selectionOnlyOneRow: PropTypes.bool,
onSelectionChange: PropTypes.func,
showSelectAllCheckbox: PropTypes.bool,
minBodyHeight: PropTypes.string,
maxBodyHeight: PropTypes.string,
};
static defaultProps = {
columns: [],
data: [],
actions: [],
isRemoteData: false,
toolbar: true,
paging: true,
search: true,
onRowClick: undefined,
onRowClickSelection: false,
selection: false,
selectionOnlyOneRow: false,
onSelectionChange: undefined,
showSelectAllCheckbox: false,
minBodyHeight: "auto",
maxBodyHeight: "auto",
};
constructor(props) {
super(props);
this.tableRef = React.createRef();
this.theme = createMuiTheme({
palette: {
secondary: {
main: "#70bbfd",
},
},
typography: {
fontFamily: "Source Sans Pro, sans-serif",
fontSize: 14,
color: "#4D4F5C !important",
},
overrides: {
MuiTableHead: {
root: {},
},
MuiTableCell: {
head: {
fontFamily: "Source Sans Pro, sans-serif",
fontSize: "14px",
backgroundColor: "#fafbfe !important",
fontWeight: 600,
padding: "9px 4px 9px 4px",
color: "#4D4F5C !important",
textAlign: "left !important",
},
root: {
fontFamily: "Source Sans Pro, sans-serif",
padding: "2px 4px 4px 4px",
borderBottom: "1px solid #fff",
color: "#4D4F5C !important",
minHeight: "40px !important",
height: "40px !important",
verticalAlign: "middle",
},
footer: {
fontFamily: "Source Sans Pro, sans-serif",
minHeight: "auto !important",
height: "auto !important",
},
},
MuiTableRow: {
root: {
"&:nth-child(odd)": {
backgroundColor: "#f4f6fd",
},
"&:nth-child(even)": {
backgroundColor: "#fafbfe",
},
"&:hover": {
backgroundColor: "#e9edf7 !important",
},
},
footer: {
backgroundColor: "#fff !important",
},
},
MuiTablePagination: {
root: {
"&:hover": {
backgroundColor: "#fff !important",
},
},
},
},
});
}
componentWillReceiveProps(newProps) {
const oldProps = this.props;
const { isRemoteData } = this.props;
if (
isRemoteData &&
oldProps.data !== newProps.data &&
newProps.data.length !== 0
) {
this.tableRef.current &&
this.tableRef.current.onQueryChange({
page: newProps.data.page,
pageSize: newProps.data.pageSize,
});
}
}
onRowClick = (event, rowData) => {
const { onRowClick, onRowClickSelection } = this.props;
if (onRowClick) {
if (onRowClickSelection) {
this.addOneRowChecked(rowData.tableData.id);
}
onRowClick(rowData);
}
};
removeFromChecked = (idx) => {
if (!this.tableRef) {
return;
}
this.tableRef.current.dataManager.changeRowSelected(false, [idx]);
};
addOneRowChecked = (idx) => {
if (!this.tableRef) {
return;
}
this.tableRef.current.onAllSelected(false);
this.tableRef.current.dataManager.changeRowSelected(true, [idx]);
};
onSelectionChange = (event) => {
const { selectionOnlyOneRow, onSelectionChange } = this.props;
if (event.length >= 1 && selectionOnlyOneRow) {
this.removeFromChecked(event[0].tableData.id);
}
if (onSelectionChange) {
onSelectionChange(event);
}
};
renderSummary() {
return (
<ListGroup>
{this.props.box.map((helpTopic) => (
<ListGroupItem key={helpTopic.help.id}> {helpTopic.help.issueName} </ListGroupItem>
))}
</ListGroup>
);
}
renderEmpy() {
return(
<Label>Kayıt Bulunamadı</Label>
);
}
render() {
const {
t,
i18n,
columns,
data,
actions,
isRemoteData,
changePageorPageSize,
toolbar,
paging,
search,
onRowClick,
selection,
showSelectAllCheckbox,
minBodyHeight,
maxBodyHeight,
} = this.props;
let columnss = [];
if (columns !== undefined) {
columnss = columns.map((key) => {
if (key.field === "checkpoint_form_name") {
return {
title: key.title,
field: key.field,
render: (rowData) => {
if (rowData["form_name"] && Array.isArray(rowData["form_name"])) {
var str = "";
rowData["form_name"].forEach(function (obj, index) {
if (index !== rowData["form_name"].length - 1) {
str += obj.toString() + ", ";
} else {
str += obj.toString();
}
});
return str;
}
},
};
} else if (key.field === "priority_trName") {
return {
title: key.title,
field: key.field,
render: (rowData) => {
switch (rowData.priority_trName) {
case "Acil":
return (
<p style={{ color: "#e1001f" }}>
{rowData.priority_trName}
</p>
);
case "Yüksek":
return (
<p style={{ color: "#ff8348" }}>
{rowData.priority_trName}
</p>
);
case "Orta":
return (
<p style={{ color: "#f6da6e" }}>
{rowData.priority_trName}
</p>
);
case "Düşük":
return (
<p style={{ color: "#70bbfd" }}>
{rowData.priority_trName}
</p>
);
}
},
};
} else if (key.field === "priority_enName") {
return {
title: key.title,
field: key.field,
render: (rowData) => {
switch (rowData.priority_enName) {
case "Urgent":
return (
<p style={{ color: "#e1001f" }}>
{rowData.priority_enName}
</p>
);
case "High":
return (
<p style={{ color: "#ff8348" }}>
{rowData.priority_enName}
</p>
);
case "Medium":
return (
<p style={{ color: "#f6da6e" }}>
{rowData.priority_enName}
</p>
);
case "Low":
return (
<p style={{ color: "#70bbfd" }}>
{rowData.priority_enName}
</p>
);
}
},
};
} else if (key.field === "status_enName") {
return {
title: key.title,
field: key.field,
render: (rowData) => {
switch (rowData.status_enName) {
case "Waiting":
return (
<Badge style={{ backgroundColor: "#f6da6e" }}>
{rowData.status_enName}
</Badge>
);
case "In Progress":
return (
<Badge style={{ backgroundColor: "#87c3f7" }}>
{rowData.status_enName}
</Badge>
);
case "Delayed":
return (
<Badge style={{ backgroundColor: "#ff8348" }}>
{rowData.status_enName}
</Badge>
);
case "Incomplete":
return (
<Badge style={{ backgroundColor: "#ff9d48" }}>
{rowData.status_enName}
</Badge>
);
case "Not Done":
return (
<Badge style={{ backgroundColor: "#e1001f" }}>
{rowData.status_enName}
</Badge>
);
case "Completed":
return (
<Badge style={{ backgroundColor: "#4ce1b6" }}>
{rowData.status_enName}
</Badge>
);
}
},
};
} else if (key.field === "status_trName") {
return {
title: key.title,
field: key.field,
render: (rowData) => {
switch (rowData.status_trName) {
case "Bekleyen":
return (
<Badge style={{ backgroundColor: "#f6da6e" }}>
{rowData.status_trName}
</Badge>
);
case "Devam Ediyor":
return (
<Badge style={{ backgroundColor: "#87c3f7" }}>
{rowData.status_trName}
</Badge>
);
case "Gecikmeli":
return (
<Badge style={{ backgroundColor: "#ff8348" }}>
{rowData.status_trName}
</Badge>
);
case "Eksik Görev":
return (
<Badge style={{ backgroundColor: "#ff9d48" }}>
{rowData.status_trName}
</Badge>
);
case "Yapılmadı":
return (
<Badge style={{ backgroundColor: "#e1001f" }}>
{rowData.status_trName}
</Badge>
);
case "Tamamlandı":
return (
<Badge style={{ backgroundColor: "#4ce1b6" }}>
{rowData.status_trName}
</Badge>
);
}
},
};
} else if (key.field === "tour_id") {
return {
title: key.title,
field: key.field,
searchable: key.searchable,
render: (rowData) => {
return i18n.language === "tr"
? "Tur " + rowData.tour_id
: "Tour " + rowData.tour_id;
},
};
} else if (key.field === "event_description") {
return {
title: key.title,
field: key.field,
searchable: key.searchable,
render: (rowData) => {
if (
rowData.event_type &&
rowData.event_type === 6 &&
rowData.form_name
) {
return i18n.language === "tr"
? rowData.form_name + " Cevaplandı "
: "Tour " + rowData.form_name + " Answered";
} else {
return i18n.language === "tr"
? rowData.description_trName
: rowData.description_enName;
}
},
};
} else {
return {
title: key.title,
field: key.field,
searchable: key.searchable,
};
}
});
}
return (
<div className="material-table__wrap" style={{ width: "100%" }}>
<MuiThemeProvider theme={this.theme}>
<MaterialTable
title="Styling with MuiThemeProvider Preview"
columns={columnss}
isLoading={data.loading}
localization={{
header: {
actions: t("material_table_localization.header.actions"),
},
toolbar: {
searchTooltip: t(
"material_table_localization.toolbar.searchTooltip"
),
searchPlaceholder: t(
"material_table_localization.toolbar.searchTooltip"
),
},
body: {
emptyDataSourceMessage:
this.props.box.length > 0
? this.renderSummary()
: this.renderEmpy(),
},
pagination: {
labelRowsSelect: t(
"material_table_localization.pagination.labelRowsSelect"
),
nextTooltip: t(
"material_table_localization.pagination.nextTooltip"
),
previousTooltip: t(
"material_table_localization.pagination.previousTooltip"
),
firstTooltip: t(
"material_table_localization.pagination.firstTooltip"
),
lastTooltip: t(
"material_table_localization.pagination.lastTooltip"
),
labelDisplayedRows: t(
"material_table_localization.pagination.labelDisplayedRows"
),
},
}}
tableRef={this.tableRef}
icons={{
Check: () => <Check />,
Export: () => <SaveAlt />,
Filter: () => <FilterList />,
FirstPage: () => <FirstPage />,
LastPage: () => <LastPage />,
NextPage: () => <ChevronRight />,
PreviousPage: () => <ChevronLeft />,
Search: () => <Search />,
ResetSearch: () => <Clear />,
ThirdStateCheck: () => <Remove />,
ViewColumn: () => <ViewColumn />,
DetailPanel: () => <ChevronRight />,
Delete: () => <DeleteOutline />,
SortArrow: (props) => <ArrowUpward {...props} fontSize="small" />,
}}
data={
isRemoteData
? (query) =>
new Promise((resolve, reject) => {
resolve({
data: data && data.data ? data.data : [],
page: data.page,
totalCount: data.totalCount,
});
})
: data || []
}
onChangePage={(page, pageSize) => {
changePageorPageSize &&
changePageorPageSize(
parseInt(page, 10),
parseInt(pageSize, 10)
);
}}
actions={actions}
components={{
Actions: (props) => (
<ButtonGroup
className="btn-group--icons table-actions-btn-group"
style={{ display: "block", marginBottom: 0 }}
>
{props.actions.map((action, index) => (
<props.components.Action
action={action}
key={"action-" + index}
data={props.data}
size={props.size}
disabled={action.disabled && action.disabled(props.data)}
hidden={action.hidden && action.hidden(props.data)}
/>
))}
</ButtonGroup>
),
Action: (props) => (
<>
<Button
id={`${props.action.name}_${props.data.tableData.id}`}
outline
style={{ marginBottom: 0 }}
disabled={props.disabled}
onClick={(event) => props.action.onClick(event, props.data)}
>
<i className={props.action.icon} />
</Button>
<UncontrolledTooltip
delay={{ show: 100, hide: 100 }}
placement="bottom"
target={`${props.action.name}_${props.data.tableData.id}`}
>
{props.action.tooltip}
</UncontrolledTooltip>
</>
),
}}
options={{
search: false,
selection: selection,
showSelectAllCheckbox: showSelectAllCheckbox,
sorting: true,
toolbar: toolbar,
showTitle: false,
paging: paging,
emptyRowsWhenPaging: false,
showFirstLastPageButtons: true,
pageSizeOptions: [10, 20, 50],
pageSize: data.pageSize || 20,
minBodyHeight: minBodyHeight,
maxBodyHeight: maxBodyHeight,
detailPanelType: "single",
rowStyle: (rowData, index) => ({
background: rowData.tableData.checked && "#e9edf7",
}),
}}
onSelectionChange={this.onSelectionChange}
onRowClick={onRowClick ? this.onRowClick : undefined}
/>
</MuiThemeProvider>
</div>
);
}
}
function mapStateToProps(state) {
return {
box: state.jobSaveReducer,
};
}
export default connect(mapStateToProps)(
withRouter(withTranslation("common")(Table))
);
```
action to add function ActionPart
```
import * as actionTypes from "./actionTypes";
export function addToHelp(helpTopic) {
return {
type: actionTypes.ADD_TO_HELP,
payload: helpTopic,
};
}
```
You forgot to add mapDispatchToProps
export default connect(mapStateToProps)( <-- HERE
withRouter(withTranslation("common")(Table))
);
Your code should be
export default connect(mapDispatchToProps, mapStateToProps)(
withRouter(withTranslation("common")(Table))
);
or you can replace mapDispatchToProps with the useDispatch Hook. The basic API looks like this:
const dispatch = useDispatch();