score:0
based on the answers above i came up with the following code.
the hook:
const usecheckpayment = ({initialvalues, sendurl, successurl, description, sum, downloadpdf}) => {
const [paid, setpaid] = usestate(false);
const [loading, setloading] = usestate(false);
const [submitting, setsubmitting] = usestate(false);
const [data, setdata] = usestate(initialvalues);
const checkorder = usecallback(
async () => {
let search = new urlsearchparams(window.location.search);
let success = search.get('success');
if (success) {
try {
const data = await getorder(search);
setdata(data);
checkpayment(search);
} catch (err) {
alert(err.message);
}
}
}, [checkpayment]
);
const checkpayment = usecallback(
async (search) => {
try {
const paid = await getpaymentstate(search);
setpaid(paid);
document.getelementbyid('myform').dispatchevent(new event('submit', { cancelable: true }))
} catch (err) {
alert(err.message);
}
}, []
);
const neworder = usecallback(
async (values) => {
setsubmitting(true);
const order = await createorder(values, description, sum);
const paymenturl = await initpayment(order, description, sum, successurl);
setsubmitting(false);
window.location.assign(paymenturl);
}, [description, sum, successurl]
);
const downloadpdf = async (values, downloaddata) => {
setloading(true);
const response = await downloadfile(downloaddata, sendurl);
setloading(false);
window.location.assign(response.pdf);
};
const onsubmit = usecallback(
async ({ values, downloaddata }) => {
if (paid) {
try {
downloadpdf(values, downloaddata);
} catch (err) {
console.log(err);
}
} else {
try {
neworder(values);
} catch (err) {
alert(err.message);
}
}
},
[paid, downloadpdf, neworder]
);
useeffect(() => {
checkorder();
}, [checkorder]);
return { onsubmit, submitting };
};
the component:
const sendurl = 'https://app.example.com/send'
const successurl = 'https://example.com/success'
const description = 'download pdf file'
const sum = '100'
const form = () => {
const handlesubmit = (values) => {
const downloaddata = {
email: values.email,
phone: values.phone
}
onsubmit({ downloaddata, values })
}
const { onsubmit, submitting } = usecheckpayment(
{sendurl, successurl, description, sum}
);
return (
<form
onsubmit={handlesubmit}
render={({ handlesubmit }) => (
<form onsubmit={handlesubmit}></form>
)}
/>
)
}
score:1
i made a quick refactor of the code and put it in a custom hook, it looks like search param is the key for when the effect needs to run.
const usecheckpayment = (search) => {
const [paid, setpaid] = usestate(false);
const [submitting, setsubmitting] = usestate(false);
const [loading, setloading] = usestate(false);
const [data, setdata] = usestate({});
const checkorder = usecallback(async () => {
let paramsearch = new urlsearchparams(search);
let success = paramsearch.get('success');
if (success) {
try {
//why not just pass it, makes getorder a little less impure
const data = await getorder(paramsearch);
setdata(data);
checkpayment(data);
} catch (err) {
alert(err.message);
}
}
}, [checkpayment, search]);
const checkpayment = usecallback(async (values) => {
try {
const paid = await getpaymentstate();
setpaid(paid);
downloadpdf(values);
} catch (err) {
alert(err.message);
}
}, []);
const downloadpdf = async (values) => {
setloading(true);
const response = await downloadfile();
setloading(false);
window.location.assign(response.pdf);
};
const neworder = async (values) => {
setsubmitting(true);
const order = await createorder();
const paymenturl = await initpayment(order);
setsubmitting(false);
window.location.assign(paymenturl);
};
const onsubmit = usecallback(
async (values) => {
if (paid) {
try {
downloadpdf(data);
} catch (err) {
console.log(err);
}
} else {
try {
neworder(values);
} catch (err) {
alert(err.message);
}
}
},
[data, paid]
);
useeffect(() => {
checkorder();
}, [checkorder]); //checkorder will change when search changes and effect is called again
return { onsubmit, submitting, loading };
};
const form = () => {
const { onsubmit, submitting, loading } = usecheckpayment(
window.location.search
);
return '';
};
score:1
you can extract out all the generic things from within the form component into a custom hook and return the required values from this hook
the values which are dependencies and will vary according to the component this is being called from can be passed as arguments to the hook. also the hook can return a onsubmit function to which you can pass on the downloaddata
const useorderhook = ({returnurl, sendurl, }) => {
const [paid, setpaid] = usestate(false);
const [submitting, setsubmitting] = usestate(false);
const [loading, setloading] = usestate(false);
const [data, setdata] = usestate({});
const checkorder = async () => {
let search = new urlsearchparams(window.location.search);
let success = search.get("success");
if (success) {
try {
const data = await getorder();
setdata(data);
checkpayment(data);
} catch (err) {
alert(err.message)
}
}
};
const checkpayment = async values => {
try {
const paid = await getpaymentstate();
setpaid(paid);
downloadpdf(values);
} catch (err) {
alert(err.message)
}
};
const downloadpdf = async values => {
setloading(true);
let downloaddata = {
email: values.email,
phone: values.phone
}
const response = await downloadfile(downloaddata, sendurl);
setloading(false);
window.location.assign(response.pdf);
}
const neworder = async (values, description, sum) => {
setsubmitting(true);
const order = await createorder(values, description, sum);
const paymenturl = await initpayment(order, description, sum, returnurl);
setsubmitting(false);
window.location.assign(paymenturl);
}
const onsubmit = async ({values, downloaddata: data, description, sum}) => {
if (paid) {
try {
downloadpdf(data);
} catch (err) {
console.log(err);
}
} else {
try {
neworder(values, description, sum)
} catch (err) {
alert(err.message)
}
}
};
useeffect(() => {
checkorder();
}, []);
return {onsubmit, loading, submitting, paid, data };
}
now you can use this hook in component like form as follows
const form = () => {
const {onsubmit, neworder, loading, submitting, paid, data } = useorderhook({returnurl: 'someurl', sendurl: 'some send url'})
const handlesubmit = (values) => {
// since this function is called, you can get the values from its closure.
const data = {email: values.email, phone: values.phone}
onsubmit({ data, values, description, sum})// pass in the required values for onsubmit here. you can do the same when you actually call neworder from somewhere
}
// this is how you pass on handlesubmit to react-final-form
return <form
onsubmit={handlesubmit }
render={({ handlesubmit }) => {
return <form onsubmit={handlesubmit}>...fields go here...</form>
}}
/>
}
Source: stackoverflow.com
Related Query
- Refactor a functional component with React hooks
- Refactor React class component into functional with hooks
- Testing React Functional Component with Hooks using Jest
- Accessing the State of a Functional Component with React Hooks when Testing with Enzyme
- Multiple times render in react functional component with hooks
- How to convert React class component to functional component with hooks
- How to test a handle function call with a react functional component with hooks
- Early return a component inside a react functional component with hooks
- Converting React class component to functional component with hooks : Problem with event listeners
- Replace State Component with Functional Component using Hooks in React
- why is a React class component converted to functional component with hooks not picking up state in event handler on document
- converting onCancel to functional component with react Hooks from class component
- Trying to convert a class based component to a functional with React Hooks
- How to use children with React Stateless Functional Component in TypeScript?
- How to implement Error Boundary with React Hooks Component
- How can I prevent my functional component from re-rendering with React memo or React hooks?
- Function inside functional component in React hooks - Performance
- Functional React Component with an argument in curly braces
- React - useRef with TypeScript and functional component
- React Hooks Const Component vs Functional Component
- Spying on React functional component method with jest and enzyme; Cannot spyOn on a primitive value
- React Navigation Header in Functional Components with Hooks
- Difference between with and without useEffect in react functional component
- Using ref with React Hooks in Ant design (antd) Table component with customized filters
- Cant use Hooks with my React Component Library. Invariant Violation: Invalid hook call
- Refactoring a React PureComponent to a hooks based functional component
- Mock React useRef or a function inside a functional component with enzyme and jest?
- How to test the state of a functional component in React with Jest (No Enzyme)
- Component name with React hooks in DevTools
- React Hooks Idle Timeout for Functional Component
More Query from same tag
- Relay Mutation is not working dynamically
- set child element to be 100% width of parent
- Visual Studio Code / React - Is there a possibility to display all possible props somewhere?
- How can I render an ArrayBuffer (PNG image) directly as an image in React?
- Webpack and Karma Testing: Uncaught ReferenceError: jQuery is not defined using
- React Router working on local but not work on real server
- Map Function Javascript - How to store 2 values when we select something in dropdown
- useForm how to setValue for dynamic input
- Refactoring from classes to functions - ways to enhance in functions
- React Redux Call action within action and get return value
- Object is possibly "null" - error with TypeScript linter
- React.PropTypes array with specific length
- how to pass the data from child component to parent component
- Can't figure out why my React Component isn't rendering?
- Compile a JSX string to a component on the fly
- Redirect to url on commponentDidMount in App.js
- Time Slider in Javascript
- Firebase 3.0 throws cross-origin error when bundled with webpack
- Material-ui horizontal menu
- React with TypeScript: how to access HOC methods in new coponent
- Why pass {...props} in a React Route?
- using immutability-helper to $merge an array
- alternative to connect using redux hooks
- How to get session in NextJS api route using with-iron-session?
- How can I use cursor: Copy with event.preventDefault()?
- React JS - Get the top of the page after refreshing the same page
- SpinButton: public property 'value' is undefined and public method 'focus()' is not a function
- How can I check the return value of dispatch in redux hook
- In React, is it possible to alter state inside of the map method, and if not what is an alternative?
- Trying to log a data object in the console using dot notation and it doesn't work, why?