Need to implement simple logic to switch the state of the buttons depending on the redux data. Initially, all buttons are true, but when I click on the Approve button, I send a request to the server, I get a response (false) and disabled button, then when I click on the Decline button, the Approve button should change the state to true, and Decline the button to false etc.
When I click on the decline button a second time, it returns state where approval is returned, how i can return a new state each time
Action
//Approve candidate
export const approveRequest = (token, id) => (dispatch) => {
dispatch({ type: 'FETCHING_ON' });
try {
axios.post(API.approveCandidateRequest + '/' + id,
{},
{headers: {"Authorization": 'Bearer ' + token.token }})
.then( (response) => {
if ( response.status === 200) {
dispatch(approveAction(response.data));
}
});
} catch (e) {
console.log(e);
}
};
//Decline Candidate
export const declineRequest = (token, id) => (dispatch) => {
dispatch({ type: 'FETCHING_OFF' });
try {
axios.post(API.declineCandidateRequest + '/' + id,
{},
{headers: {"Authorization": 'Bearer ' + token.token }})
.then( (response) => {
if ( response.status === 200) {
dispatch( declineAction( response.data) );
}
});
} catch (e) {
console.log(e);
}
};
Reducer
case 'SET_DECLINE_DATA_STATUS':
return {
...state,
isDecline: action.isDecline,
mergeDeclineDataToMessage: state.me.messages.push(action.isDecline.data.message)
};
case 'FETCHING_ON':
return {
...state,
isDecline: null
};
case 'SET_APPROVE_DATA_STATUS':
return {
...state,
isApprove: action.isApprove,
mergeApproveToMessage: state.me.messages.push(action.isApprove.data.message)
};
case 'FETCHING_OFF':
return {
...state,
isApprove: null
};
Logic
const ShareContacts = ( { messages, getProfileShare, declineRequest, isDecline, isApprove, approveRequest } ) => {
const shared = messages.me ? messages.me.account.shared : null;
const id = messages.me ? messages.me.account.id : null;
const [ roleId, setRoleId ] = useState('');
const [ token, setToken ] = useState('');
let declineIsDisabled = false;
let approveIsDisabled = false;
if ( isApprove && isApprove.data.is_approved !== null && isApprove.data.is_approved !== undefined
&& isApprove.data.is_approved === true ) {
approveIsDisabled = true;
declineIsDisabled = !approveIsDisabled;
console.log('isApprove', 1);
}
if (isDecline && isDecline.data.is_approved !== null && isDecline.data.is_approved !== undefined
&& isDecline.data.is_approved === false ) {
declineIsDisabled = true;
approveIsDisabled = !declineIsDisabled;
console.log('isDecline', 2)
}
isDecline = isApprove = null;
useEffect( () => {
const token = JSON.parse(localStorage.getItem("user-data"));
getProfileShare(token);
setRoleId(token.roleId);
setToken(token)
}, []);
const [open, setOpen] = useState(false);
const openModal = () => {
setOpen(true);
};
const closeModal = () => {
setOpen(false);
};
const handleApproveRequest = (e) => {
e.preventDefault();
approveRequest(token, id);
};
const handleDeclineRequest = (e) => {
e.preventDefault();
declineRequest(token, id)
};
return(
<ShareButtons>
{
roleId === 1 ? !shared ? (<Button size='tiny' color='green' onClick={openModal}>Share Contact</Button>) : null
: roleId === 2 ? shared ? (
<Flex>
<Button size='tiny' disabled={ approveIsDisabled }
onClick={handleApproveRequest} color='green'>Approve</Button>
<Button size='tiny' disabled={ declineIsDisabled }
onClick={handleDeclineRequest} color='red'>Decline</Button>
<Button size='tiny' color='grey' onClick={openModal}>Open Contacts</Button>
</Flex>
) : null :null
}
{
roleId === 1 ? (<UserDataModal open={open} closeModal={closeModal} /> )
: roleId === 2 ? ( <RecruiterDataModal id={id} open={open} closeModal={closeModal} /> ) : null
}
</ShareButtons>
);
};
Related
I'm using ink package, and I'm building the following component:
MultiSelect.tsx file:
import React, { useEffect, useState } from 'react';
import { useStdin } from 'ink';
import type { ISelectItem, ISelectItemSelection } from './interfaces/select-item';
import { ARROW_DOWN, ARROW_UP, ENTER, SPACE } from './constants/input';
import MultiSelectView from './MultiSelect.view';
interface IProps {
readonly items: ISelectItem[];
readonly onSubmit: (selectedItems: string[]) => void;
}
const MultiSelect: React.FC<IProps> = (props: React.PropsWithChildren<IProps>) => {
const { stdin, setRawMode } = useStdin();
const [itemsSelectionState, setItemsSelectionState] = useState<ISelectItemSelection[]>(
props.items.map((item, index) => ({ ...item, selected: false, isHighlighted: index === 0 })),
);
const stdinInputHandler = (data: unknown) => {
const rawData = String(data);
if (rawData === ARROW_DOWN) {
setItemsSelectionState((prev) => {
const highlightedIndex = prev.findIndex((item) => item.isHighlighted);
if (highlightedIndex === -1) {
return prev;
}
const clonedPrev = structuredClone(prev);
clonedPrev[highlightedIndex]!.isHighlighted = false;
if (highlightedIndex === prev.length - 1) {
clonedPrev[0]!.isHighlighted = true;
} else {
clonedPrev[highlightedIndex + 1]!.isHighlighted = true;
}
return clonedPrev;
});
}
if (rawData === ARROW_UP) {
setItemsSelectionState((prev) => {
const highlightedIndex = prev.findIndex((item) => item.isHighlighted);
if (highlightedIndex === -1) {
return prev;
}
const clonedPrev = structuredClone(prev);
clonedPrev[highlightedIndex]!.isHighlighted = false;
if (highlightedIndex === 0) {
clonedPrev[prev.length - 1]!.isHighlighted = true;
} else {
clonedPrev[highlightedIndex - 1]!.isHighlighted = true;
}
return clonedPrev;
});
}
if (rawData === SPACE) {
setItemsSelectionState((prev) => {
const highlightedIndex = prev.findIndex((item) => item.isHighlighted);
if (highlightedIndex === -1) {
return prev;
}
const clonedPrev = structuredClone(prev);
clonedPrev[highlightedIndex]!.selected = !prev[highlightedIndex]!.selected;
return clonedPrev;
});
}
if (rawData === ENTER) {
const selectedItemsValues = itemsSelectionState
.filter((item) => item.selected)
.map((item) => item.value);
props.onSubmit(selectedItemsValues);
}
};
useEffect(() => {
setRawMode(true);
stdin?.on('data', stdinInputHandler);
return () => {
stdin?.removeListener('data', stdinInputHandler);
setRawMode(false);
};
}, []);
return <MultiSelectView itemsSelection={itemsSelectionState} />;
};
export default MultiSelect;
MultiSelect.view.tsx file:
import { Box, Text } from 'ink';
import React from 'react';
import type { ISelectItemSelection } from './interfaces/select-item';
interface IProps {
readonly itemsSelection: ISelectItemSelection[];
}
const MultiSelectView: React.FC<IProps> = (props: React.PropsWithChildren<IProps>) => {
return (
<Box display="flex" flexDirection="column">
{props.itemsSelection.map((item) => (
<Box key={item.value} display="flex" flexDirection="row">
<Text color="blue">{item.isHighlighted ? '❯' : ' '}</Text>
<Text color="magenta">
{item.selected ? '◉' : '◯'}
</Text>
<Text color="white" bold={item.selected}>
{item.label}
</Text>
</Box>
))}
</Box>
);
};
export default MultiSelectView;
Then, when I use this component in my code:
const onSubmitItems = (items: string[]) => {
console.log(items);
};
render(<MultiSelect items={items} onSubmit={onSubmitItems} />);
the render function is imported from ink and items is something like [{value: 'x', label: 'x'}, {value:'y', label:'y'}]
When I hit the enter key, Then onSubmitItems is triggered, but it outputs empty list, although I did select some items...
For example, in this output:
I picked 3 items, but output is still empty list. And it does seem like the state changes, so why I don't get the updated state?
You can resolve the issue by using useCallback:
const stdinInputHandler = useCallback((data: Buffer) => {
const rawData = String(data);
if (rawData === ARROW_DOWN) {
setItemsSelectionState((prev) => {
const highlightedIndex = prev.findIndex((item) => item.isHighlighted);
if (highlightedIndex === -1) {
return prev;
}
const clonedPrev = structuredClone(prev);
clonedPrev[highlightedIndex]!.isHighlighted = false;
if (highlightedIndex === prev.length - 1) {
clonedPrev[0]!.isHighlighted = true;
} else {
clonedPrev[highlightedIndex + 1]!.isHighlighted = true;
}
return clonedPrev;
});
}
if (rawData === ARROW_UP) {
setItemsSelectionState((prev) => {
const highlightedIndex = prev.findIndex((item) => item.isHighlighted);
if (highlightedIndex === -1) {
return prev;
}
const clonedPrev = structuredClone(prev);
clonedPrev[highlightedIndex]!.isHighlighted = false;
if (highlightedIndex === 0) {
clonedPrev[prev.length - 1]!.isHighlighted = true;
} else {
clonedPrev[highlightedIndex - 1]!.isHighlighted = true;
}
return clonedPrev;
});
}
if (rawData === SPACE) {
setItemsSelectionState((prev) => {
const highlightedIndex = prev.findIndex((item) => item.isHighlighted);
if (highlightedIndex === -1) {
return prev;
}
const clonedPrev = structuredClone(prev);
clonedPrev[highlightedIndex]!.selected = !prev[highlightedIndex]!.selected;
return clonedPrev;
});
}
if (rawData === ENTER) {
const selectedItemsValues = itemsSelectionState
.filter((item) => item.selected)
.map((item) => item.value);
props.onSubmit(selectedItemsValues);
}
}, [itemsSelectionState]);
Then, in your useEffect:
useEffect(() => {
setRawMode(true);
stdin?.on('data', stdinInputHandler);
return () => {
stdin?.removeListener('data', stdinInputHandler);
setRawMode(false);
};
}, [stdinInputHandler]);
now useEffect will re-register the input handler with new functions locals up-to-date with the state
I have a state which I need to update with the ID returned from an endpoint call so I can call another another endpoint using that ID, I've made a state in the parent component and I use it in my first form to set the ID. I pass that id as a prop to the component that needs it but when I console.log the state, it doesn't change.
How can I pass the ID through the components?
I've added comments on the main places to look at
Here is my first form where I need the ID from -
const AddWebAppTypeForm = (props: any, ref: any) => {
const { setWebAppTypes, setNewAppValues}: AddWebAppTypeFormProps =
props;
const {
handleSubmit,
control,
reset,
formState: { isDirty },
} = useForm();
const onSubmit = (data: any) => {
let formData = new FormData();
formData.append("name", data.Title);
formData.append("description", data.Description);
formData.append("uploaded_file", data.Image[0]);
if (isDirty) {
createWebAppType(formData);
}
};
const createWebAppType = async (body: any) => {
await fetch(`${process.env.REACT_APP_API_URL}/webapptype`, {
method: "POST",
body: body,
})
.then((response) => response.json())
.then((data: IWebAppType) => {
const model: IWebAppType = {
id: data.id,
name: data.name,
image: data.image,
description: data.description,
image_url: data.image_url,
};
setNewAppValues(model.id); // <--- Set the state here
setWebAppTypes((prev) =>
prev.map((item) => (item.id === 0 ? model : item))
);
enqueueSnackbar(`Created App Succesfully`, {
variant: "success",
});
});
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<button hidden={true} ref={ref} type="submit" />
</form>
);
};
export default forwardRef(AddWebAppTypeForm);
My parent component with the states -
function WebAppTypeAccordion({ a, setWebAppTypes }: WebAppTypeAccordionProps) {
const [formEl, setFormEl] = useState(null);
const [addFormEl, setAddFormEl] = useState(null);
const [newAppValues, setNewAppValues] = useState<number>(0); // <--- state with 0 as initialised value
const handleRef = (el: any) => {
if (el !== null) {
setFormEl(el);
}
};
const handleAddRef = (el: any) => {
if (el !== null) {
setAddFormEl(el);
}
};
return (
<Accordion defaultExpanded={a.id === 0}>
<AccordionSummary
// onClick={(e) => handleOnClick(a, e)}
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography>{a.name}</Typography>
</AccordionSummary>
<AccordionDetails>
{a.id === 0 ? (
<AddWebAppTypeForm
setWebAppTypes={setWebAppTypes}
ref={handleAddRef}
setNewAppValues={setNewAppValues} // <--- Passing setState to set id
/>
) : (
null
)}
<MappedAccordion
waobj={a}
key={a.id}
setWebAppTypes={setWebAppTypes}
editRef={formEl}
addRef={addFormEl}
newAppValues={newAppValues} // <--- Passing ID
/>
</AccordionDetails>
</Accordion>
);
}
export default WebAppTypeAccordion;
Here is where I am trying to use the ID to call another endpoint
function MappedAccordion({
waobj,
setWebAppTypes,
editRef,
addRef,
newAppValues,
}: MappedAccordionProps) {
const handleCreate = (data: FieldT) => {
let wtype: string = String(waobj.id);
if (addRef !== null) {
if (newAppValues !== 0) {
wtype = String(newAppValues); // <--- Try to use the ID but get default value
createFetch(data, wtype); // <--- Try to use the ID but get default value
}
}
createFetch(data, wtype);
};
const createFetch = (data: FieldT, wtype: string) => {
let formData = new FormData();
formData.append("name", data.name);
formData.append("link", data.link);
formData.append("wtype", wtype);
fetch(`${process.env.REACT_APP_API_URL}/webapp/`, {
method: "POST",
body: formData,
})
.then((response) => {
if (!response.ok) {
let err = new Error("HTTP status code: " + response.status);
enqueueSnackbar(`Environment already exists`, {
variant: "error",
});
throw err;
}
return response.json();
})
.then((data: IWebApp) => {
const model: FieldT = {
wid: data.id,
name: data.name,
link: data.link,
};
enqueueSnackbar(`Created Environment ${model.wid}`, {
variant: "success",
});
});
};
const onSubmit = (data: FormFields) => {
if (addRef !== null) addRef?.click(); // <--- Submit AddWebAppTypeForm form, set the ID
else editRef?.click();
let onSubmitData: FieldT[] = data.myFieldValues;
onSubmitData.map((a: FieldT, index) => {
let originalField: FieldT = initialFields[index];
if (a.wid === undefined) {
handleCreate(a);
} else {
if (JSON.stringify(a) !== JSON.stringify(originalField)) {
handleEdit(a);
}
}
});
};
return (
<div>
<form onSubmit={handleSubmit(onSubmit)} id="environment-form">
<div style={{ paddingTop: 10 }}>
<Button
type="submit" // <--- Submit form
variant="outlined"
size="small"
sx={{ marginRight: 1 }}
>
Save
</Button>
<Button
variant="outlined"
size="small"
onClick={handleAppDelete}
disabled={waobj.id === 0 ? true : false}
>
Delete
</Button>
</div>
</form>
</div>
);
}
export default MappedAccordion;
Thanks for taking a look, I appreciate any help!
How to map through two arrays and send data as props to other component? I want to send data from price and gamedet as a prop to Wishlist Component.As I am new to react, suggest me if this code is not good or unclean too, thanks in advance.
This is the dumb way I send whole array to Wishlist component :
price.map((game1) => {
let temp = {
steamAppID: game1.steamAppID,
storeID: game1.storeID,
normalPrice: game1.normalPrice,
salePrice: game1.salePrice,
};
console.log("temp sale", temp.salePrice);
return tempArr1.push(temp) && tempArr2.push(temp.steamAppID));
})
This is all of WishListData component:
import React, { useEffect, useState } from "react";
import Wishlist from "./Wishlist";
import "./Wishlist.css";
import "animate.css";
import axios from "axios";
const WishlistData = () => {
const [gamedet, setGameDet] = useState([]);
const [loaded, setLoaded] = useState(false);
const [stores, setStores] = useState([]);
const [price, setPrice] = useState([]);
const [wishlist, setWishlist] = useState([]);
useEffect(() => {
setWishlist(
localStorage.getItem("Wishlist")
? JSON.parse(localStorage.getItem("Wishlist"))
: []
);
}, []);
const RemoveFromWishlist = (id) => {
let newList = wishlist.filter((game) => game.gameID !== id);
setWishlist(newList)
localStorage.setItem("Wishlist", JSON.stringify(newList));
console.log("id", [wishlist.pop(id)]);
console.log("newlist", wishlist);
setGameDet([])
};
const DET_URL = `https://api.rawg.io/api/games`;
useEffect(() => {
let isCancelled = false;
const RAWGdet = () => {
wishlist &&
wishlist.map(async (game, index) => {
const res = await axios({
url: `https://cors-anywhere.herokuapp.com/${DET_URL}/${game.gameID}?key=${process.env.REACT_APP_RAWG_KEY}`,
headers: {
"X-Requested-With": "XMLHttpRequest",
},
method: "GET",
});
if (!isCancelled) {
setGameDet((gamedet) => gamedet.concat(res.data));
}
setLoaded(true);
});
};
RAWGdet();
return () => {
isCancelled = true;
};
}, [DET_URL, wishlist]);
useEffect(() => {
let isCancelled = false;
const CSPrice = () => {
wishlist &&
wishlist.map(async (game, index) => {
const res = await axios({
url: `https://cors-anywhere.herokuapp.com/${DET_URL}/${game.slug}/stores?key=${process.env.REACT_APP_RAWG_KEY}`,
headers: {
"X-Requested-With": "XMLHttpRequest",
},
method: "GET",
});
if (!isCancelled) {
setStores((stores) => stores.concat(res.data));
}
setLoaded(true);
});
};
CSPrice();
return () => {
isCancelled = true;
};
}, [DET_URL, wishlist]);
let stm = [];
stores
.map((steam) => {
return steam.results;
})
.filter((item) => {
return item.map((id) => {
return id.store_id === 1 ? stm.push(id.url) : <>{null}</>;
});
});
let idmain = [];
stm.map((steamid) => {
return steamid.split("/").map((item) => {
return idmain.push(item);
});
});
useEffect(() => {
let isCancelled = false
wishlist.length !==0 &&
wishlist.map((game, index) => {
return (
<div key={index}>
{axios
.get(
`https://www.cheapshark.com/api/1.0/deals?storeID=1&steamAppID=${game.steamID}`
)
.then((res) => {
if (!isCancelled){
setPrice((price) => price.concat(res.data));
setLoaded(true)
}
})
.catch((err) => {
console.log("ERR", err);
})}
</div>
);
});
return () => {
isCancelled = true
}
}, [wishlist]);
let tempArr1 = [];
let tempArr2 = [];
if (loaded ) {
return (
<div className="animate__animated animate__slideInDown">
<div className="wishlist_header">
<h3>Your Wishlist</h3>
</div>
{wishlist.length !== 0 ? (
price.map((game1) => {
let temp = {
steamAppID: game1.steamAppID,
storeID: game1.storeID,
normalPrice: game1.normalPrice,
salePrice: game1.salePrice,
};
console.log("temp sale", temp.salePrice);
return tempArr1.push(temp) && tempArr2.push(temp.steamAppID));
}) &&
gamedet.map((game, index) => {
// console.log("mad2", game.name);
return (
<div id="wishlist_ctn" key={index}>
<Wishlist
// key={index}
title={game.name}
steamRatingCount={game.id}
// steamRatingPercent={game[0].steamRatingPercent}
// savings={game[0].savings}
// normalPrice={}
// salePrice={salePrice}
steamAppID={tempArr2}
data={tempArr1}
image={game.background_image}
rem={() => RemoveFromWishlist(game.id)}
/>
</div>
);
})
) : (
<div className="wishlist_header">
<h3>Add Games!!</h3>
</div>
)}
</div>
);
} else {
return (
<div className="hmm">
<div className="wishlist_header">
<h3>Your Wishlist</h3>
</div>
<div className="wishlist_header">
<h3>Loading Games</h3>
</div>
);
</div>
);
}
};
export default WishlistData;
I don't understand why you need two extra arrays since you are mapping price to populate
tempArr1, which contain a copy of its items, and tempArr2, which contains a copy of its steamAppIDs.
I think you could just pass the price array as data, and a mapped version as steamAppID:
{wishlist.length !== 0 ?
(gamedet.map((game, index) => {
<Wishlist
// key={index}
title={game.name}
steamRatingCount={game.id}
// steamRatingPercent={game[0].steamRatingPercent}
// savings={game[0].savings}
// normalPrice={}
// salePrice={salePrice}
steamAppID={price.map(item => item.steamAppID)}
data={price}
image={game.background_image}
rem={() => RemoveFromWishlist(game.id)}
/>;
</div>
);
})
) : (
<div className="wishlist_header">
<h3>Add Games!!</h3>
</div>
)}
I am new to react, I am trying to write a react component, component has several features.
user can input a random number, then number will be displayed in the
page too.
implement a button with text value 'start', once click the button,
the number value displayed will reduce one every 1second and the
text value will become 'stop'.
continue click button, minus one will stop and text value of button
will become back to 'start'.
when number subtracted down to 0 will automatically stop itself.
I have implemented first three features. but I am not sure how do I start the last one. should I set another clearInteval? based on if statement when timer counts down 0?
code is here:
var myTimer;
class App extends Component {
constructor(props) {
super(props);
this.state = {
details: [{ id: 1, number: "" }],
type: false
};
this.handleClick = this.handleClick.bind(this);
}
changeNumber = (e, target) => {
this.setState({
details: this.state.details.map(detail => {
if (detail.id === target.id) {
detail.number = e.target.value;
}
return detail;
})
});
};
handleClick = () => {
this.setState(prevState => ({
type: !prevState.type
}));
if (this.state.type === false) {
myTimer = setInterval(
() =>
this.setState({
details: this.state.details.map(detail => {
if (detail.id) {
detail.number = parseInt(detail.number) - 1;
}
return detail;
})
}),
1000
);
}
if (this.state.type === true) {
clearInterval(myTimer);
}
};
render() {
return (
<div>
{this.state.details.map(detail => {
return (
<div key={detail.id}>
Number:{detail.number}
<input
type="number"
onChange={e => this.changeNumber(e, detail)}
value={detail.number}
/>
<input
type="button"
onClick={() => this.handleClick()}
value={this.state.type ? "stop" : "start"}
/>
</div>
);
})}
</div>
);
}
}
export default App;
just add
if (detail.number === 0) {
clearInterval(myTimer);
}
in
handleClick = () => {
this.setState(prevState => ({
type: !prevState.type
}));
if (this.state.type === false) {
myTimer = setInterval(
() =>
this.setState({
details: this.state.details.map(detail => {
if (detail.id) {
detail.number = parseInt(detail.number) - 1;
if (detail.number === 0) {
clearInterval(myTimer);
}
}
return detail;
})
}),
1000
);
}
if (this.state.type === true) {
clearInterval(myTimer);
}
};
Here You have this solution on Hooks :)
const Test2 = () => {
const [on, setOn] = useState(false)
const initialDetails = [{ id: 1, number: "" }]
const [details, setDetails] = useState(initialDetails)
const changeNumber = (e, target) => {
setDetails({ details: details.map(detail => { if (detail.id === target.id) { detail.number = e.target.value; } return detail; }) });
if (this.state.details.number === 0) { setOn(false) }
};
const handleClick = () => {
if (on === false) {myTimer = setInterval(() =>
setDetails({details: details.map(detail => {if (detail.id) {detail.number = parseInt(detail.number) - 1; if (detail.number === 0) {clearInterval(myTimer);} }
return detail;})}),1000);}
if (on === true) { clearInterval(myTimer); }
};
return (
<div>
{details.map(detail => {
return (
<div key={detail.id}>
Number:{detail.number}
<input
type="number"
onChange={e => changeNumber(e, detail)}
value={detail.number}
/>
<input
type="button"
onClick={() => handleClick()}
value={on ? "stop" : "start"}
/>
</div>
);
})}
</div>
)
}
I have this button in react
{editing && (
<Button extraClasses="m1" onClick={this.handleEditing} type="submit">
Save
</Button>
)}
But the submit doesn't work, if I delete the onClick, the submit works. How can I make both, the onClick and the submit to work?
This is the onSubmit event:
handleSubmit(e) {
e.preventDefault();
const params = this.state.params || this.props.selected.params;
const { exportTypes } = this.props;
const {
startDate: startDateMoment,
endDate: endDateMoment,
companyId,
exportTypeId,
id,
} = this.state;
const type = exportTypes.find(o => o.id === Number(exportTypeId));
let enrichedParams = [];
if (type.params.length > 0) {
enrichedParams = params.reduce((acc, { paramName, paramValue }) => {
const { id: exportParameterId } = type.params.find(p => p.name === paramName);
return [...acc, { exportParameterId, paramName, paramValue }];
}, []);
}
const startDate = startDateMoment.format();
const endDate = endDateMoment.format();
const record = { companyId, exportTypeId, startDate, endDate, id, params: enrichedParams };
const filteredQuery = Object.keys(record).reduce(
(acc, k) => (record[k] ? { ...acc, [k]: record[k] } : acc),
{},
);
if (!Object.keys(filteredQuery).length) return;
this.props.updateExport(filteredQuery);
}
You could remove the onClick event handler from your Button and invoke the handleEditing method inside your handleSubmit method instead.
Example
class App extends React.Component {
handleEditing = () => {
// ...
};
handleSubmit = (e) => {
// ...
this.handleEditing();
};
render() {
return (
<div>
{/* ... */}
{editing && (
<Button extraClasses="m1" type="submit">
Save
</Button>
)}
{/* ... */}
</div>
);
}
}