Javascript 当单击加载相同表单的链接组件时,Redux表单会清空自身

Javascript 当单击加载相同表单的链接组件时,Redux表单会清空自身,javascript,reactjs,redux-form,react-router-v4,react-router-redux,Javascript,Reactjs,Redux Form,React Router V4,React Router Redux,我有一个配置文件页面,其中包含一个redux表单ProfileForm,我为它设置了一些初始值。在我的页面标题中,我有一个到/profile路由的react router链接 第一次加载页面时,表单已正确初始化。但是,如果我单击链接元素,表单会自动清空。我希望表单保持由redux表单状态维护的值(或者至少初始化为initialValues) 我做错了什么?有解决办法吗 注意:我使用的是react 16、react路由器4和redux表单7。在获取数据时,我还在动作生成器中使用redux thun

我有一个配置文件页面,其中包含一个redux表单
ProfileForm
,我为它设置了一些
初始值。在我的页面标题中,我有一个到
/profile
路由的react router
链接

第一次加载页面时,表单已正确初始化。但是,如果我单击
链接
元素,表单会自动清空。我希望表单保持由redux表单状态维护的值(或者至少初始化为initialValues)

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

注意:我使用的是react 16、react路由器4和redux表单7。在获取数据时,我还在动作生成器中使用redux thunk

代码 Profile.js

//src/components/App.js
render() {
    return (
        <div className="App">
            <Header />
            <Main />
        </div>
    );
}
//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;
}
组件
Profile
在第一次呈现
ProfileForm
之前,等待设置
initialValues
。它显示了一个
加载
组件,直到获取数据为止

//...
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)
);
Main.js

//src/components/App.js
render() {
    return (
        <div className="App">
            <Header />
            <Main />
        </div>
    );
}
//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;
}
由于React Router v4位于
/profile

//src/components/main.js
render(){
    return (
        <Switch>
            <Route path='/profile' component={Profile}/>
            ...
        </Switch>
    )
}
减速器

//src/components/App.js
render() {
    return (
        <div className="App">
            <Header />
            <Main />
        </div>
    );
}
//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;
}

您的问题是表单由于任何原因被卸载/装载,我浏览了一下您的代码,我的第一个想法是加载
组件。当它呈现时,该窗体不会显示。您可以执行以下操作:

隐藏表单而不是将其删除(将isVisible或其他内容传递给表单),或者让redux表单在卸载表单时为您保留状态。您可以通过将prop
destroonunmount=false
设置为
reduxForm
hoc来实现这一点

您是否尝试过将组件包装到withRouter HOC?@Sujit.Warrier我刚刚尝试将withRouter HOC添加到我的组件中,但仍然存在相同的问题。
BasicInformation Form
做什么?您只将
初始值
传递给表单。还有什么是
这个.props.submitData
?似乎没有一个名为action generator的操作生成器,您将在哪里调度您的操作?你在回叫中使用了redux thunks和dispatch吗?@C5H8NNaO4我在准备问题时有几个拼写错误<代码>基本信息表单
档案表单
submitData
是一个动作生成器,用于调度动作。我确实在使用
redux-thunk
。我正在更新问题中关于操作和还原的更多细节。您确定
response.data
包含有效的json吗?您不需要对结果调用
json()
response.json()。然后((json)=>dispatch({payload:json}))
destroonunmount
设置为
false
成功了,谢谢!现在我也明白了背后的道理。