React Redux Form模态框预填值传父组件:代码缺失点排查
Fixing Your Redux Form Modal with Parent-Child Data Flow
Let's walk through the gaps and bugs in your code step by step to get the modal working as expected—pre-filling the input, passing updated values back to the parent, and managing modal visibility properly.
Parent Component Issues & Fixes
- No way to open the modal
YourisOpenModalstate starts asfalse, but there's no trigger to toggle it open. We'll add an "Open Modal" button and corresponding handler. - Incorrect
onSavebinding
You passedonSave={this.handleSave}to the modal, buthandleSavedoesn't exist. It should point to yoursubmitActionmethod, which will receive the updated value from the modal. - Redundant Redux Form setup
The form logic lives entirely in the modal, so the parent doesn't need to be wrapped withreduxFormor useformValueSelector—this was causing unnecessary confusion. - Missing value update logic
YoursubmitActionneeds to actually update the parent'smyVariable(I'll assume it's local state here; adjust to dispatch a Redux action if it's stored in the global state).
Fixed Parent Component Code
// import statements import React, { Component } from 'react'; import MyModal from './MyModal'; export class ParentComponent extends Component { constructor(props) { super(props); // Initialize local state with incoming myVariable (adjust if using Redux) this.state = { isOpenModal: false, myVariable: props.myVariable || '' }; this.handleOpenModal = this.handleOpenModal.bind(this); this.handleCloseModal = this.handleCloseModal.bind(this); this.submitAction = this.submitAction.bind(this); } handleOpenModal() { this.setState({ isOpenModal: true }); } handleCloseModal() { this.setState({ isOpenModal: false }); } submitAction(values) { console.log('submit action ', values); // Update parent's state with the new value and close the modal this.setState({ myVariable: values.myVariable, isOpenModal: false }); // If using Redux, replace setState with a dispatch: // this.props.updateMyVariable(values.myVariable); } render() { const { isOpenModal, myVariable } = this.state; return ( <div> <p>Current Value: {myVariable}</p> {/* Button to trigger modal open */} <button onClick={this.handleOpenModal}>Open Modal</button> <MyModal isOpenModal={isOpenModal} onSave={this.submitAction} onClose={this.handleCloseModal} myVariable={myVariable} /> </div> ); } } // Uncomment below if using Redux to connect parent to store // const mapStateToProps = (state) => ({ // myVariable: state.yourReducer.myVariable // }); // const mapDispatchToProps = (dispatch) => ({ // updateMyVariable: (value) => dispatch(updateMyVariableAction(value)) // }); // export default connect(mapStateToProps, mapDispatchToProps)(ParentComponent); export default ParentComponent;
Modal Component Issues & Fixes
- Broken initialValues handling
Modifying a globalinitialValuesobject in the render method is bad practice and won't update when the modal reopens. Instead, we'll use Redux Form'senableReinitializeto refresh the initial value from props every time the modal opens. - No data passed back to parent
YourhandleSubmitfunction doesn't send the updated values to the parent—we need to callprops.onSave(values)to complete the data flow. - Incorrect mapStateToProps
The initial value should come directly from the parent'smyVariableprop, not from the form state. We'll fix this to pull values from props. - Modal visibility not controlled
YourCustomModalwasn't receiving theisOpenModalprop or a close handler. We'll pass these in so the modal can toggle visibility correctly. - Missing required propTypes
You didn't define propTypes foronSave,onClose, andmyVariable—these are critical for the component to work as expected.
Fixed Modal Component Code
// import statements import React, { Component } from 'react'; import { Field, reduxForm } from 'redux-form'; import PropTypes from 'prop-types'; export class MyModal extends Component { handleSubmit = (values) => { // Pass updated values back to the parent this.props.onSave(values); }; render() { const { isOpenModal, onClose, handleSubmit } = this.props; return ( <CustomModal isOpen={isOpenModal} onClose={onClose} // Pass close handler to your modal component > <form onSubmit={handleSubmit(this.handleSubmit)}> <div> <Field name='myVariable' label='TEST' type='text' component={renderInputField} /> </div> <div> <button type='submit'>Save</button> <button type='button' onClick={onClose}>Cancel</button> </div> </form> </CustomModal> ); } } MyModal.propTypes = { isOpenModal: PropTypes.bool.isRequired, onSave: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired, myVariable: PropTypes.string.isRequired, handleSubmit: PropTypes.func.isRequired // Provided by reduxForm }; // Helper for your input field (ensure this is defined!) const renderInputField = ({ input, label, type, meta: { touched, error } }) => ( <div> <label>{label}</label> <input {...input} type={type} /> {touched && error && <span className="error">{error}</span>} </div> ); const formName = 'modalForm'; // Map parent's myVariable prop to form initialValues const mapStateToProps = (state, ownProps) => ({ initialValues: { myVariable: ownProps.myVariable } }); export default reduxForm({ form: formName, enableReinitialize: true, // Critical: Refreshes form when initialValues changes onSubmitFail: (errors, dispatch) => { // Implement your focusOnField logic here, e.g.: // const firstErrorKey = Object.keys(errors)[0]; // dispatch(focus(formName, firstErrorKey)); } })(connect(mapStateToProps)(MyModal));
Key Takeaways
enableReinitialize: true: This is non-negotiable—it tells Redux Form to update the initial input value whenever the parent'smyVariablechanges (like when reopening the modal).- Clear Data Flow: Parent passes initial value → modal pre-fills form → user submits → modal sends new value back → parent updates its state/Redux store.
- Modal Control: Always pass a close handler to the modal so users can cancel, and ensure the modal respects the parent's
isOpenModalprop.
内容的提问来源于stack exchange,提问作者Sanath
相关产品推荐
相关产品推荐

