单击加载相同表单的 Link 组件时,Redux-form 会自行清空

Redux-form empties itself when clicking on a Link component which loads the same form

我有一个包含 redux-form ProfileForm 的个人资料页面,我为其设置了一些 initialValues。在我的页眉中,我有一个反应路由器 Link/profile 路线。

第一次加载页面时,表单被正确初始化。但是,如果我单击 Link 元素,表单将自行清空。我本来希望表单保持其值由 redux-form 状态维护(或者至少初始化为 initialValues)。

我做错了什么?有解决方法吗?

注意:我正在使用 react 16、react-router 4 和 redux-form 7。在获取数据时,我也在我的动作生成器中使用 redux-thunk。

代码

Profile.js

组件 Profile 在第一次渲染 ProfileForm 之前等待设置 initialValues。在获取数据之前,它会显示一个 Loading 组件。

//...
import { 
    fetchData,
    submitData,
} from '../../actions';

class Profile extends Component{
    componentDidMount() {
        this.props.fetchData();
    }

    render(){
        if(!this.props.initialValues){
            return <Loading />
        }else{
            return <ProfileForm initialValues={this.props.initialValues} />
        }
    }
}


class ProfileForm extends Component{
    onSubmit(values){
        return this.props.submitData(values);
    }

    render(){
        const { handleSubmit } = this.props;
        return (
            <div>
                <Form 
                    onSubmit={handleSubmit(this.onSubmit.bind(this))}
                    className="container">
                    <Field
                        name="first_name"
                        type="text" 
                        title="First name" 
                        component={SingleInput} />

                    ...

                    <Button type="submit" 
                        Sumbit
                    </Button>
                </Form>
            </div>
        )
    }
}

// validate, warn, etc.
// ...

function mapStateToProps(state) {
    return { 
        initialValues: state.profile.data // set by the profile reducer upon fetching the data
    };
}

export default connect(mapStateToProps,{ fetchData })(Profile);

ProfileForm = reduxForm({
    form: 'ProfileForm',
    fields: ['first_name', ...],
    enableReinitialize: true,
    validate,
    warn,
})(
    connect(mapStateToProps, { submitData })(ProfileForm)
);

App.js

//src/components/App.js
render() {
    return (
        <div className="App">
            <Header />
            <Main />
        </div>
    );
}

Header.js

Header 组件包含指向 /profileLink 组件。

//src/components/header.js
render(){
    return (
        ...
        <Link className="nav-link" to="/profile">Profile</Link>
        ...
    )
}

Main.js

由于 /profile

下的 React-Router v4,我有一个可以访问的个人资料页面
//src/components/main.js
render(){
    return (
        <Switch>
            <Route path='/profile' component={Profile}/>
            ...
        </Switch>
    )
}

编辑:动作生成器和缩减器

我正在使用 axios 获取和提交数据,并在收到数据后使用 redux-thunk 发送回调。

动作发生器

//src/actions/index.js
export function fetchData(){
    return (dispatch) => {
        axios.get(`${FETCH_URL}`)
            .then(response => {
                dispatch({
                    type: FETCH_DATA_SUCCESS,
                    payload: response.data
                });
            })
            .catch(error => {
                dispatch({
                    type: FETCH_DATA_FAILED,
                    payload: error
                })
            })
    }
}

export function submitData(values){
    return (dispatch) => {
        return axios.post(`${SUBMIT_URL}`,values)
                    .then(response => {
                        dispatch({ 
                            type: SUBMIT_DATA_SUCCESS,
                            payload: values,
                        });
                    })
                    .catch(error => {
                        dispatch({
                            type: SUBMIT_DATA_FAILED,
                            payload: error
                        });
                    })
    };
}

减速机

//src/reducers/profile.js
export default function(state={}, action) {
    switch(action.type) {
        case FETCH_DATA_SUCCESS:
            return { ...state, profile: action.payload };
        case FETCH_DATA_FAILED:
            // Note that I never reach this
            return { ...state, profile: {} };
        case SUBMIT_DATA_SUCCESS:
            return { ...state, profile: action.payload };
        case SUBMIT_DATA_FAILED:
            return { ...state };
    }
    return state;
}

你的问题是表单是 unmounted/mounted 不管什么原因,我看了一眼你的代码,我的第一个想法是 Loading 组件。当它呈现时,表单不是。您可以做的是以下几点: 隐藏表单而不是删除它(将 isVisible 或其他内容传递给表单)或让 redux-form 在卸载表单时为您保留状态。您可以通过将道具 destroyOnUnmount=false 设置为 reduxForm hoc 来做到这一点。