如何在向reducer调度操作时阻止本地状态重置?

时间:2018-04-13 13:21:34

标签: reactjs redux reducers

我正在构建一个简单的数据库,我正在实施搜索条件表单。我想仅在提交表单时向Reducer 发送操作。

const mapDispatchToProps = dispatch => {
return {
    onSubmittedForm: (criteria) => dispatch(compActions.submitCriteria(criteria))
};

};

criteria是存储的对象是本地状态:

state = {
    criteria: {
        group: '',
        province: '',
        realms: []
    }
}

并以相同的方式(当前)在Reducer中。

当我向Reducer发送操作时,本地状态会重置。我可以在Reducer中正确地看到标准,然后将它们正确地映射到 props 。当地的州也很好。

要初始化Criteria组件,我使用:

<Criteria
     options={this.props.options}
     realms={this.state.criteria.realms}
     realmsChanged={this.handleCriteriaRealmsChange}
     formSubmitted={this.handleCriteriaFormSubmission}
 />

realms是其中一项标准。

我被迫使用本地状态,否则,每当输入发生变化时我都必须向Reducer发送操作(以便能够从this.props.criteria.realms获取更新的值而不是{{ 1}},就像现在一样)也可以正常工作,但基本要求是仅在表单提交时更新Reducer'状态,而不是在输入更改时。

为了反映这个问题,我们很容易将其用作类似的值:

this.state.criteria.realms

但我知道这不是正确的方法。

也许有一种方法可以在将动作发送到Reducer之后保持状态不变?你能告诉我吗?

更新

我简化了组件。目前,在每次更改时,组件(以及依赖于const realms = (this.props.criteria.realms && this.props.criteria.realms.length > 0) ? this.props.criteria.realms : this.state.criteria.realms; 的所有其他组件)都会重新呈现,因为onChange会将新的<Criteria />值调度到Reducer(然后映射到group)。这有效但我只想在通过点击按钮提交表单时对所有组件执行重新渲染。

目前,this.props.criteria.group不执行任何操作,因为状态已因onChange而更新。

这就是为什么我认为本地状态的想法会起作用但不会因为onCriteriaFormSubmission字段期望值必须为group如果我已经将它传递给Reducer,否则它总是为空。 ..

因此,我唯一想到的是在单个条件字段更改时不将标准值传递给Reducer(在这种情况下为this.props.criteria.groups,但可以更多)但不知何故将它们全部一起提交表格提交:groups)。但是,我最终陷入无限循环,因为当条件字段发生变化时,我无法显示真值。

onCriteriaFormSubmission

使用RESOLUTION更新2:

我在提交时尝试了提交事件的preventDefault()方法,在评论中提出但它也没有帮助。我开始认为问题可能在其他地方,在组件之外,因为状态明显在调度时重置(提交表单不会导致重置)。

我开始了解React Router和Store持久性,并决定仔细检查Redux实现。

我的index.js是这样的:

import React, { Component } from 'react';
import Select from '../../UI/Inputs/Select/Select';
import { Button, Form } from 'semantic-ui-react';
import * as companiesActions from '../../../store/actions/companies';
import { connect } from 'react-redux';
class Criteria extends Component {

render = () => {
    return (
        <section>
            <Form onSubmit={this.props.onCriteriaFormSubmission}>
                <Form.Field>
                    <Select
                        name='group'
                        options={this.props.options.groups}
                        placeholder="Choose group"
                        multiple={false}
                        value={this.props.criteria.group}
                        changed={this.props.onGroupChange}
                    />
                </Form.Field>
                <Button
                    type='submit'
                    primary>
                    Search
                </Button>
            </Form>
        </section>
    );
}

}

const mapStateToProps = state => {
return {
    criteria: state.r_co.criteria,
    options: {
        groups: state.r_op.groups
    }
};
};

const mapDispatchToProps = dispatch => {
return {
    onCriteriaFormSubmission: (criteria) => dispatch(companiesActions.criteriaFormSubmission(criteria)),
    onGroupChange: (event, data) => dispatch(companiesActions.groupChange(event, data))
};
};

export default connect(mapStateToProps, mapDispatchToProps)(Criteria);

在App.js中,我的<Provider store={store}> <App /> </Provider> <BrowserRouter>组件包裹着。一旦我将<Aux>直接移到<BrowserRouter>下,重置问题就会消失,所有内容都应该像现在一样。

所以我的index.js现在是

<Provider>

2 个答案:

答案 0 :(得分:0)

虽然在表单提交后我从未必须保留本地状态,但这种行为似乎很奇怪。您是否可以对处理表单的方法使用preventDefault来阻止页面在提交后重新加载?

如果有效,请告诉我。

答案 1 :(得分:0)

您似乎没有阻止表单重新加载的默认行为(假设您将提交处理程序放在表单而不是按钮上。这是您应该尝试的:在您的render方法之前创建一个submit方法。方法应该使用参数&#39; event&#39;然后在调用方法将表单数据发送到存储之前调用prevent default方法。

criteriaSubmisssion = event => { event.preventDefault(); this.props.onCriteriaFormSubmission() }

您的表单OnSubmit方法应该调用criteriaSubmission。