admin管理员组文章数量:1401143
First of all here is my code in react
import { useFormState, useFormStatus } from 'react-dom'
import { submitAction } from './action.ts'
export default function Calculator() {
const [result, submitAction] = useFormState(submitForm, null)
return (
<>
<form action={submitAction}>
[input fields]
<button type="reset">
Reset
</button>
<CalculateButton />
</form>
<Table headers={inputsCols}>
{result ? (
Object.entries(result).map(([rowKey, rowData], rowIndex) => (
<TableRow key={rowIndex}>
<TableCell key={rowKey} className="font-bold">
{rowKey}
</TableCell>
{Object.entries(rowData).map(([dataKey, dataValue]) => (
<TableCell key={`${rowKey}-${dataKey}`}>{dataValue}</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={inputsCols.length}>No data available</TableCell>
</TableRow>
)}
</Table>
</>
)
}
function CalculateButton() {
const { pending } = useFormStatus()
return (
<Button
type="submit"
color="orange"
disabled={pending}
icon={pending ? LoadingIcon : undefined}
>
Calculate
</Button>
)
}
I am trying to use reacts server action to submit a form and I want to reset
- the form state and
- the results returned from the server action
when user clicks the reset button.
the first thing working fine with using button type="reset" inside the form but for the second one I am not quite sure how should I do it.
So, How can I reset the state returned from useFormState in react js? to update the UI so user can enter some other data and do other calculations.
First of all here is my code in react
import { useFormState, useFormStatus } from 'react-dom'
import { submitAction } from './action.ts'
export default function Calculator() {
const [result, submitAction] = useFormState(submitForm, null)
return (
<>
<form action={submitAction}>
[input fields]
<button type="reset">
Reset
</button>
<CalculateButton />
</form>
<Table headers={inputsCols}>
{result ? (
Object.entries(result).map(([rowKey, rowData], rowIndex) => (
<TableRow key={rowIndex}>
<TableCell key={rowKey} className="font-bold">
{rowKey}
</TableCell>
{Object.entries(rowData).map(([dataKey, dataValue]) => (
<TableCell key={`${rowKey}-${dataKey}`}>{dataValue}</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={inputsCols.length}>No data available</TableCell>
</TableRow>
)}
</Table>
</>
)
}
function CalculateButton() {
const { pending } = useFormStatus()
return (
<Button
type="submit"
color="orange"
disabled={pending}
icon={pending ? LoadingIcon : undefined}
>
Calculate
</Button>
)
}
I am trying to use reacts server action to submit a form and I want to reset
- the form state and
- the results returned from the server action
when user clicks the reset button.
the first thing working fine with using button type="reset" inside the form but for the second one I am not quite sure how should I do it.
So, How can I reset the state returned from useFormState in react js? to update the UI so user can enter some other data and do other calculations.
Share Improve this question edited Jan 15, 2024 at 18:37 Aashutosh Kumar asked Jan 14, 2024 at 18:00 Aashutosh KumarAashutosh Kumar 812 silver badges5 bronze badges 1-
1
I like to return a key from my server action, like
key: new Date.now()
, and then use auseEffect
hook. Source: robinwieruch.de/next-forms – Robin Wieruch Commented Mar 18, 2024 at 7:38
2 Answers
Reset to default 4It doesn't appear there is a way to re-initialize the form state from within the ponent rendering the form. You can, however, use a React key to reset the form from outside.
See Resetting a form with a key.
Use some state to represent a "form key" such that you can provide a new React key and effectively remount the Calculator
ponent which will have the initial state.
export default function Calculator({ onReset }) {
const [result, submitAction] = useFormState(submitForm, null)
return (
<>
<form action={submitAction} onReset={onReset}>
...input fields...
<button type="reset">
Reset
</button>
<CalculateButton />
</form>
...
</>
)
}
const [formKey, setFormKey] = React.useState(() => nanoid());
const updateFormKey = () => setFormKey(nanoid());
...
<Calculator key={formKey} onReset={updateFormKey} />
Basic Demo
const submitForm = (previousState, formData) => {
console.log({ previousState });
return previousState + 1;
};
function Calculator({ onReset }) {
const [result, submitAction] = ReactDOM.useFormState(submitForm, 0);
return (
<React.Fragment>
<form action={submitAction} onReset={onReset}>
<div>Result: {result}</div>
<button type="reset">
Reset
</button>
<CalculateButton />
</form>
</React.Fragment>
);
}
function CalculateButton() {
const { pending } = ReactDOM.useFormStatus()
return (
<button
type="submit"
disabled={pending}
>
Calculate ({pending ? "loading" : "idle" })
</button>
);
}
const App = () => {
const [formKey, setFormKey] = React.useState(0);
const updateFormKey = () => setFormKey(key => key + 1);
return <Calculator key={formKey} onReset={updateFormKey} />;
};
const rootElement = document.getElementById("root");
const root = ReactDOM.createRoot(rootElement);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
<script src="https://cdnjs.cloudflare./ajax/libs/react/18.3.0-canary-cb2439624-20231219/umd/react.development.min.js" integrity="sha512-DyF9mlaay3VPTJNySTYIgb2dsv0NXOcY/IRkCFm/1J/w4B3oOXA6LGwS04cgMFHcSB5b7WXqbOsBaAsWsvcj8g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/18.3.0-canary-cb2439624-20231219/umd/react-dom.development.min.js" integrity="sha512-kkJ9iTzcc6cLoFeK+Kp13xvLpIa/+if1NSX7R1ThvHgw6VccDudy8qb5FGyismOvnaGfI604s7ZD6Rzu4Awpng==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="root" />
useFormState
is now useActionState
(from react
core) but the API remains the same.
Here's one possible solution, wrapping the original useActionState
to provide a reset function:
import {
useCallback,
useState,
useEffect,
useRef,
useActionState as useReactActionState,
} from 'react'
export function useActionState<State, Payload>(
...args: Parameters<typeof useReactActionState<State, Payload>>
): [
...ReturnType<typeof useReactActionState<State, Payload>>,
resetActionState: () => void,
] {
const [state, dispatch, isPending] = useReactActionState(...args)
const [currentState, setCurrentState] = useState(state)
const currentStateRef = useRef(currentState)
currentStateRef.current = currentState
useEffect(() => {
if (currentStateRef.current !== state) {
currentStateRef.current = state
setCurrentState(state)
}
}, [state])
const [, initialState] = args
const reset = useCallback(() => {
currentStateRef.current = initialState
setCurrentState(initialState)
}, [initialState])
return [currentState, dispatch, isPending, reset]
}
Bear in mind that this will introduce an additional render cycle because of the setCurrentState
call.
You can use it like so:
const [result, submitAction, , resetFormState] = useActionState(submitForm, null)
// ...
// something happened, reset form state
resetFormState()
本文标签: javascriptHow to reset the state returned from useFormState in react jsStack Overflow
版权声明:本文标题:javascript - How to reset the state returned from useFormState in react js? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744289030a2599024.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论