UNREGISTER_FIELD on Unmount even with destroyOnUnmount: false
I have a Redux Form with a nested field. When my component renders, it maps through the Redux store at Key1
(a nested object that exists independently of the form) and populates a Dropdown with each nested Key2
(to clarify, these are different keys). When a user selects a Key2
from the dropdown, it creates an input for each value like so: <Field name="key1.key2" />
. This registers the nested field in our redux form as expected and allows us to update and filter accordingly.
However, when a user no longer wants this Key2
and deletes the input, it removes the input and dispatches the UNREGISTER_FIELD
action creator thereby removing Key2
from our store entirely. Other answers have pointed me to the destroyOnUnmount
option, but even with destroyOnUnmount: false, forceUnregisterOnUnmount: false
the field is destroyed from both the form and the redux store when the input unmounts.
I would be totally fine if it destroyed the field in the form, but I do not want the field to be removed from the pre-existent object in the store.
See also questions close to this topic
-
Update screen with reducer in react native
im trying to add a picture in the task, and after this, update the flatlist to see the update but it does not with. It works if I close and return on the app. If I display the store, I also see an instant update but not in my screen.
Here is a part of my code :
TaskImage.js
openImageLibrary=async(task)=>{ const result = await ImageHelpers.openImageLibrary(); if(result){ const downloadUrl=await this.uploadImage(result,task) this.props.UpdateTaskImage({...task,uri:downloadUrl}) } } .... const mapStateToProps=state=>{ return{ tasks:state.tasks }; } const mapDispatchToProps=dispatch=>{ return{ loadTasks:tasks=> dispatch({type:'LOAD_TASKS_FROM_SERVER',payload:tasks}), addTask:task=>dispatch({type:'ADD_TASK',payload:task}), DeleteTask: task=>dispatch({type:'DELETE_TASK',payload:task}), UpdateTaskImage:task=>dispatch({type:'UPDATE_TASK_IMAGE',payload:task}) } }
TasksReducer.js :
const initialState={ tasks:[], image:null } const tasks=(state=initialState,action)=>{ switch(action.type) { case 'LOAD_TASKS_FROM_SERVER': return{ ...state, tasks:action.payload }; case 'UPDATE_TASK_IMAGE': return{ ...state, tasks:state.tasks.map(task=>{ if(task.task==action.payload.task) { return {...task,image:action.payload.uri} } return task }) } default: return state; } }; export default tasks;
Any idea..?
-
Is it okay to dispatch slice's action from another action in redux-toolkit?
I'm using redux-toolkit and have 2 slices: "auth" and "profile"
auth => handle information about token
profile => handle information about user accountWhen user tries to login, I send request to api, that returns me the user token and account information. Then I need to save this information. I put token to corresponding field (in same slice). And I need to put my account information to "profile" slice (login processing takes place in the "auth" slice). Now i'm just dispatch setProfile action from 'auth' slice.
Is it anti-pattern to dispatch "profile" action from "auth" slice? Or I have to move this logic from redux to component? Or make "login" action outside of slice? Or do I need to keep it all in one slice?
// PROFILE SLICE | profile.js const initialState = { data: {}, status: 'idle' } export const profileSlice = createSlice({ name: 'profile', initialState, reducers: { setProfile(s, {payload: profile}) { s.profile = profile } } }) export const {setProfile} = userSlice.actions; export default profileSlice.reducer // AUTH SLICE | auth.js import {setProfile} from './profile' // import action creator from profile slice const initialState = { token: null, status: 'idle' } export const authSlice = createSlice({ name: 'auth', initialState, reducers: { setToken(s, {payload: token}) { s.token = token } } }) export const login = ({email, password}) => dispatch => { return api.auth.login({ email, password }) .then(res => { const {token, ...profile} = res.data dispatch(setToken(token)) dispatch(setProfile(profile) }) } export const {setToken} = authSlice.actions; export default authSlice.reducer
-
useSelector hook for functions?
I can't use the actions and state elements, as my component has its own props. So i am using useSelector (react hook) and would like to do the same for actions, but can't figure out how to do it... Any idea?
interface MyComponentProps { item: Item; theFunctionIWouldLikeToUse: Function; } const MyComponent= ({ item, theFunctionIWouldLikeToUse }: MyComponentProps ) => { const myStateItem: any= useSelector( (state: State) => state.myStateItem, ) ; //I would like to do the same for the function };
Can I use useSelector or useDispatch to get my function, which is currently in connect?
export default connect(() => ({}), { theFunctionIWouldLikeToUse, })(withTranslation('admin')(MyComponent));
-
Images not displaying on material-ui card component
I am trying to get my photos to display on an iterated card component in Material-UI. I have checked all my Redux store and the URL's they relate to all bring up images when enter them on the address bar in Firefox so the links are working ok. If my file path in the backend is just backend/assets/article then the file number does this matter? I thought I had the asset folder set as public with Express but does there need to be an actual 'public' folder?
Is there anything obvious I am doing wrong trying to get this displayed? I have only got imported components working before and not managed URL's from my backend / Redux Store. Could this be the JSS of the card component?
<CardMedia id="Photos" className={classes.media} image={{uri: photos}} title="Dive Photos"/> <CardContent>
jss
media: { height: 70, paddingTop: '56.25%', // 16:9 },
-
Is there a react redux dispatch schedule?
I need to know, when i call something like:
dispatch( firstStuff() ); dispatch( secondStuff() );
if there is something like a schedule in react-redux, that gives me the guaranty, that these 2 lines will be dispatched in the right sequence. Or is it possible that if my app has a small frame brake-in for example, it will be dispatched in a different order?
Thank you for any answere
-
Redux-toolkit create action prepare doesn't add the values for Typescript
I'm following the official example here redux-toolkit reference and trying to type the PayloadAction as followed :
import { createSlice, PayloadAction, nanoid, } from '@reduxjs/toolkit' type MyObjectType = { uuid: string anotherProp: string // ... } const slice = createSlice({ name: 'oneSlice', initialState: {}, reducers: { addSomething: { reducer(state, action: PayloadAction<{x: string; anotherProp: string}>) { const { x, uuid, anotherProp } = action.payload // got an error here on uuid // do something with { x, uuid, anotherProp } // I need to use it as index : state.something[uuid] = { uuid: uuid, anotherProp: anotherProps } }, prepare(x: string, anotherProp: string) { return { payload: { uuid: nanoid(), x, anotherProp, }, } }, } } })
However I got an error trying to destructuring
action.payload
. How to infer theuuid
attribute ofaction.payload
?I've come to a weird solution where I pass the whole object type in PayloadAction and modify the uuid inside
prepare()
... addSomething: { reducer(state, action: PayloadAction<{x: string; myobject: MyObjectType}>) { const { x, myobject } = action.payload // there is no problem here }, prepare(x: string, myobject: MyObjectType) { myobject.uuid = nanoid() return { payload: { x myobject: myobject }, } }, } ...
Is there a better way to resolve this ?
-
Uploading a file using redux-form to node js
hello i'm a using a redux-form wizzard in which i'm trying to upload an image to my nodejs server. this is my code on submit
<Form onSubmit={async (values) => { console.log(values.img); console.log(values.img[0]); console.log(values); setShowLoader(false); const [, err] = await queryServerApi( "deliveryman/add", values, "POST", false ); if (err) { setShowLoader(false); setError({ visible: true, message: JSON.stringify(err.errors, null, 2), }); } }} />
and this is the result console result
the problem is that the image is not uploading from the front(reactjs).. this is not a backend problem because the upload is working fine via the backend
-
Redux Form - Reset on an Initialized form doesn't seem to work?
I have several forms that have been built with Redux Forms (v8.3.6). On a new form, if information is input in the form and then I click on Clear Form to reset the form, the form clears all fields as expected. However, if I initialize a form, add any new information to that form, then click on Clear Form to reset the form, only the new information gets cleared. Any data originally initialized in the form remains. I do see in the redux dev tools that the RESET action gets triggered. Is this expected behavior?
I know this is odd, but I have a user that has a need to be able to clear a series of forms, and she's needs to do that manually at the moment. TIA
Here is an example of one of my forms:
import React, { Component } from "react"; import { Field, reduxForm } from "redux-form"; import { connect } from "react-redux"; import { Row, Col } from "react-bootstrap"; import renderInputField from "../../common/formComponents/InputField"; import renderTextAreaField from "../../common/formComponents/TextAreaField"; import renderSelectField from "../../common/formComponents/SelectField"; import validators, { length } from "redux-form-validators"; import * as permits from "../../../redux/actions/PermitActions"; import Spinner from "../../common/SpinnerGif"; import LoginPage from "../../common/LoginPage"; /*Override redux form validator defaults*/ Object.assign(validators.defaultOptions, { dateFormat: "mm/dd/yyyy", allowBlank: true }); class PermitModificationForm extends Component { constructor(props) { super(props); this.state = { isLoading: false, disabled: false }; } componentDidMount() { if (this.props.location.state.permit) { this.props.initialize(this.props.location.state.permit); } this.props.change("lastModifiedBy", this.props.user.profile.email); } onSubmit = (data, dispatch) => { debugger; const { facilityId, permitId, modId } = this.props.match.params; const { facility, user } = this.props.location.state; if (data.modificationIdPk) { try { this.setState({ isLoading: true, disabled: true }); return dispatch(permits.updatePermitModification(facilityId, permitId, modId, facility.facilityName, data)); } catch (err) { this.setState({ isLoading: false, disabled: false }); alert("Submission Error: ", err); } } try { this.setState({ isLoading: true, disabled: true }); return dispatch(permits.createPermitModification(facilityId, permitId, data, facility)); } catch (err) { this.setState({ isLoading: false, disabled: false }); alert("Submission Error: ", err); } }; render() { const { handleSubmit, pristine, reset, submitting, location, user } = this.props; const yesNo = ["No", "Yes"]; const modType = ["Major", "Minor"]; if (!location.state.facility) { return <Spinner />; } if (!user || user === null) { return <LoginPage appName="DWMRC Solid Waste Database" message={"Not Authorized"} />; } return ( <form onSubmit={handleSubmit(this.onSubmit)} className="page-form"> <Row> <Col xs={9}> <h4>{location.state.facility.facilityName.toUpperCase()}</h4> <br /> </Col> <Col xs={3}> <h4>Permit Modification</h4> <br /> </Col> </Row> <Row> <Col> <Field label="Modification Type" name="modificationType" component={renderSelectField}> {modType.map((type) => ( <option key={type} value={type}> {type} </option> ))} </Field> </Col> <Col> <Field label="Date Requested" name="modifactionRequest" component={renderInputField} type="date" placeholder="mm/dd/yyyy" /> </Col> <Col> <Field label="Modification Description" name="modificationDescription" component={renderTextAreaField} type="text" validate={length({ maximum: 500 })} /> </Col> </Row> <Row> <Col> <Field label="Comment Period Began" name="commentPeriodStart" component={renderInputField} type="date" placeholder="mm/dd/yyyy" /> </Col> <Col> <Field label="Comment Period Ended" name="commentPeriodEnd" component={renderInputField} type="date" placeholder="mm/dd/yyyy" /> </Col> <Col> <Field label="Public Hearing Required" name="publicHearing" component={renderSelectField}> {yesNo.map((yn) => ( <option key={yn} value={yn}> {yn} </option> ))} </Field> </Col> <Col> <Field label="Public Hearing Date" name="publicHearingDate" component={renderInputField} type="date" placeholder="mm/dd/yyyy" /> </Col> </Row> <Row> <Col> <Field label="Date Modification Approved" name="modificationApproved" component={renderInputField} type="date" placeholder="mm/dd/yyyy" /> </Col> <Col> <Field label="Date Effective" name="effectiveDate" component={renderInputField} type="date" placeholder="mm/dd/yyyy" /> </Col> <Col> <Field label="Modification Tracking Number" name="pmTrackingNumber" component={renderInputField} type="text" /> </Col> </Row> <Row> <Col> <Field label="Comments" name="comments" component={renderTextAreaField} type="text" validate={length({ maximum: 500 })} /> </Col> </Row> <div> <button type="submit" className="btn btn-secondary" disabled={pristine || this.state.disabled}> {this.state.isLoading ? "Submitting" : "Submit"} </button> <button type="button" className="btn btn-warning" disabled={pristine || submitting} onClick={reset}> {" "} Clear Values{" "} </button> </div> </form> ); } } const mapStateToProps = (state) => ({ PermitModificationForm: state.form.PermitModificationForm, user: state.oidc.user }); PermitModificationForm = connect(mapStateToProps)(PermitModificationForm); export default reduxForm({ form: "PermitModificationForm", enableReinitialize: true, keepDirtyOnReinitialize: true })(PermitModificationForm);
-
Is there some way to validate redux-form in a custom input?
I need to throw a validation error from my custom input component, and not let the user successfully submit the form. In this Codesandbox, I'm passing the
maxLength
prop to theField
with a custom input componentRenderField
. I want to validate themaxLength
within theRenderField
(see the comments in the Codesandbox).Some observations:
- I can't pass a validate prop to the
Field
, neither atreduxForm
decorator. This is due to an architecture decision. - The max length example at the Sandbox is only to illustrate what I need. I know I can pass
maxLength
to the input component if I need to validate it, but my real problem is not about a string's max length.
- I can't pass a validate prop to the
-
[Semantic Dropdown]_jquery2.default(...).dropdown is not a function on trying to access dropdown
I am trying to access my Dropdown throught jquery and apply 'restore default' operation on the same.
I am created a 'multiple' 'searchable' dropdown inside a form(). I am trying to access the dropdown using: $('.ui.dropdown),but on invoking dropdown('restore defaults') on the same, I get exception
_jquery2.default(...).dropdown is not a function
. It may be happening because it is not a tag.Can you help what am I missing? Also, is there any other way of resetting a dropdown on the basis of some event.
-
onSubmit triggers on every change, basic form did not
I'm converting a project to use Semantic-UI-React and a form is triggering on every change. The old form looked like this and worked as intended:
<div className="entryForm"> <form onSubmit={this.handleSubmit}> <span className="formLabel">Location:</span> <input type='text' name="location" placeholder="Location" onChange={this.handleChange} autoComplete="off" /><br/> Date Activity: <input type='text' name="activity" placeholder="Activity" onChange={this.handleChange} autoComplete="off"/><br/> Cuisine: <input type='text' name="cuisine" placeholder="Cuisine" onChange={this.handleChange} autoComplete="off"/> <button type="submit" value="submit" hidden="hidden"/> </form></div>
The Semantic form looks like this and displays both SUBMIT and HELP on every change in the form:
<Form onSubmit={console.log("SUBMIT")} onChange={console.log("HELP")}> <Form.Field inline> <label>Location:</label> <Input name='location' placeholder='Enter a neighborhood here' onChange={this.handleChange} autoComplete="off"/> </Form.Field> <Form.Field inline> <label>Activity:</label> <Input name='activity' placeholder='Enter a a fun activity' onChange={this.handleChange} autoComplete="off"/> </Form.Field> <Form.Field inline> <label>Cuisine:</label> <Input name='cuisine' placeholder='What do you want to eat' onChange={this.handleChange} autoComplete="off"/> </Form.Field> </Form>
What's going on?