I use reactjs. But when I handle onClick event. After I clicked on Button and dispatch an event. It's clear all my data in Input. I don't know why the data is cleared and how can prevent it.
import React, { useEffect } from "react";
import { Input, Form, Checkbox, Button, Row, Col, notification } from "antd";
import { loginRequest } from "../../../store/userStore";
import { useDispatch, useSelector } from "react-redux";
export default function SignInPage() {
const dispatch = useDispatch()
const handleSubmit = (e) => {
dispatch(loginRequest());
}
return (
<>
<Input>
</Input>
<Input>
</Input>
<Button onClick={() => {
handleSubmit()
}}>Click</Button>
</>
)
}
Issue
I'm guessing these inputs and button are being rendered with a form element and you aren't preventing the default form action from occurring. Button elements have a type="submit" by default, so when clicked will invoke the default form action and reload the page (clearing the inputs).
Solution
Call preventDefault on the event object.
const handleSubmit = (e) => {
e.preventDefault(); // <-- prevent the default
dispatch(loginRequest());
}
Related
I am having multiple tab, each tabs load different components. In each components I have different set of forms. So there is a generic footer where user can click on save or continue.
So I am trying to use the react hook form useContext, but I am not getting the values.
I have reproduced the same issue on the below code.
SaveAndContinue component
import React from "react";
import { useFormContext } from "react-hook-form";
const Footer = (props) => {
const { formState, handleSubmit } = useFormContext();
const onSaveDetails = (data) => {
console.log("onSaveDetails", data);
};
const onContinue = (data) => {
console.log("onContinue", data);
};
return (
<>
<button
disabled={!formState?.isDirty}
onClick={handleSubmit(onSaveDetails)}
>
Save
</button>
<button disabled={!formState?.isDirty} onClick={handleSubmit(onContinue)}>
Continue
</button>
</>
);
};
export default Footer;
How can I get the formData of each component form when clicking on the save or continue button using react hook form context
Any help is appreciated
Here is the codesandbox
I looked at your codesandbox. the problem is:
on your ServiceDetails and UserDetails components you should register your inputs using useFormContext not useForm:
const { register } = useFormContext({
mode: "onBlur",
reValidateMode: "onChange",
defaultValues: {
firstName: ""
}
});
I am creating a React component using an npm wysiwyg. When the page loads, I grab some user data from a context I have set up. I grab the user's name and cover letter which is some html code. When the page loads I want to change the wysiwyg's state to contain the cover letter that way it displays it to the user. It works the first time the page loads, however if I hit refresh or try to open the page again, the contents of the wysiwyg disappear. Upon inspection of the console, I am met with a
Warning: Can't call `setState` on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the n component.
I am unsure of what I am doing wrong.
Here is my component:
import React, { useContext, useEffect, useState } from 'react';
import { LoggedInContext } from './contexts/LoggedIn';
import { Editor } from 'react-draft-wysiwyg';
import { EditorState, ContentState } from 'draft-js';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
import htmlToDraft from 'html-to-draftjs';
import './Profile.css';
const ProfileSettings = () => {
const { user, coverLetter } = useContext(LoggedInContext);
const blocksFromHtml = htmlToDraft(coverLetter);
const { contentBlocks, entityMap } = blocksFromHtml;
const contentState = ContentState.createFromBlockArray(
contentBlocks,
entityMap
);
const editorState = EditorState.createWithContent(contentState);
const [editorStateReact, setEditorStateReact] = useState(editorState);
const onEditorStateChange = (editorState) => {
setEditorStateReact(editorState);
};
return (
<div className="Profile">
<h2>User: {user}</h2>
<Editor
editorState={editorStateReact}
toolbarClassName="toolbarClassName"
wrapperClassName="wrapperClassName"
editorClassName="editorClassName"
onEditorStateChange={onEditorStateChange}
/>
<button className="btn btn-lg btn-primary my-3">Save Profile</button>
</div>
);
};
export default ProfileSettings;
I have an antd form where I am able to get the form data in onFinish function upon hitting submit button in which I wanted to use uesEffect hook and dispatch an action with form data as payload to redux saga but I got following error
React Hook "useEffect" is called in function "onFinish" that is neither a React function component nor a custom React Hook function.
If I write useEffect hook outside the onFinsh function, I am unable to get the form data/values
Please suggest a workaround to get the form data values outside of onFinish function
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Form, Input, Button, Checkbox } from 'antd';
const Demo = () => {
const onFinish = (values) => {
// alert(JSON.stringify(values['username']));
useEffect(() => {
// dispatch an action with values as payload
}, []);
};
console.log(values) // UNABLE TO GET VALUES HERE...HOW TO GET IT???
return (
<Form
name="basic"
onFinish={onFinish}>
<Form.Item
label="Username"
name="username">
<Input />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
};
ReactDOM.render(<Demo />, document.getElementById('container'));
It looks like you don't even need the useEffect() hook. Just dispatch the action from within the onFinish() and have state store the values
const Demo = () => {
const [ values, setValues ] = useState([]);
const onFinish = (recievedValues) => {
// dispatch here
setValues(recievedValues);
}
console.log(values) // <-- you can get it here
return (<div> ... </div>);
};
Or better yet, since you are already saving the values in redux during dispatch, you should use that in your render code as well:
import { useSelector } from 'react-redux';
const Demo = () => {
//point to the state where your data is
const stateValues = useSelector(state => state.your.data);
const onFinish = (recievedValues) => {
// dispatch here
}
console.log(stateValues) // <-- you can get it here
return (<div> ... </div>);
};
useEffect can only be called at the top level of your component, not within a function. In this case, you shouldn't need useEffect to dispatch the action, and instead can just do so directly inside onFinish.
state-machine with react-hook-form to make my forms, but after submit the form i want to clear the storage after submit;
This is how i create my store;
createStore({
data: {}
});
And this is my Submit function
const onSubmit = (data:any) => {
action(data);
props.onSubmit(state.data);
// I need a function to clear the data to not complete my forms after i submit
}
Here a little example that i want:
https://codesandbox.io/s/delete-data-little-state-machine-q3w0g
In "step3"i want to clear the data after click on button
It looks like you need to create another action and pass that to the hook. You can see examples of this in the docs. Here is a working example:
clearAction.js
export default function clearAction(state, payload) {
return {
data: {}
};
}
Step3.js
import React from "react";
import { useForm } from "react-hook-form";
import { withRouter } from "react-router-dom";
import { useStateMachine } from "little-state-machine";
import clearAction from "./clearAction";
const Step3 = (props) => {
const { register, handleSubmit } = useForm();
const { state, action } = useStateMachine(clearAction);
const onSubit = (data) => {
action(data);
props.history.push("./resultFinal");
console.log(state, action);
action();
};
return (
<form onSubmit={handleSubmit(onSubit)}>
<h2>Clear Data</h2>
<input type="submit" />
</form>
);
};
export default withRouter(Step3);
Note in the examples provided in the docs you can pass multiple actions to the hook as needed.
I using library react-redux-toastr for our project. This library works great, except this case: codesandbox:
import React from "react";
import { useCallback } from "react";
import debounce from "lodash/debounce";
import { toastr } from "react-redux-toastr";
export default function Input({ value, onChange }) {
const toast = useCallback(
debounce(() => {
toastr.error("Interupt your typing", "Sorry, I blur your text input");
}, 500)
);
const setValue = e => {
onChange(e.target.value);
toast();
};
return (
<input
style={{ width: 500 }}
type="text"
value={value}
onChange={setValue}
/>
);
}
Basically, we want to let user keep typing in, and debouncedly call some API to update the input to database. Everything an API call is successful, show the toast. However, whenever the toast is displayed, the text input is unfocused.
in the CodeSandbox demo, you can try to type in anything, and see what the problem is.
Thanks.