Как предотвратить сброс локального состояния при отправке действия редуктору?

Я создаю простую базу данных и использую форму критериев поиска. Я хочу отправить действие в 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 вместо 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; 

но я знаю, что это неправильный подход.

Возможно, есть способ сохранить состояние нетронутым после отправки действия в Reducer? Могли бы вы, пожалуйста, посоветовать?


ОБНОВЛЕНИЕ

Я упростил компонент. В настоящее время при каждом изменении компонент (и все другие компоненты, зависящие от <Criteria />) повторно визуализируются, поскольку onChange отправляет новое значение group в Reducer (который затем сопоставляется с this.props.criteria.group). Это работает, но я хочу выполнить повторную визуализацию для всех компонентов только тогда, когда я отправляю форму нажатием кнопки.

В настоящее время onCriteriaFormSubmission ничего не делает, потому что состояние уже обновлено из-за onChange.

Вот почему я думал, что идея локального состояния будет работать, но это не так, потому что поле group ожидает значение, которое должно быть this.props.criteria.groups, если я уже передаю его в Reducer, иначе оно всегда будет пустым ...

Поэтому единственное, что мне приходит в голову, - это не передавать значения критериев в Reducer при изменении одного поля критериев (в данном случае groups, но их может быть больше), а каким-то образом отправлять их все вместе при отправке формы через: onCriteriaFormSubmission). Однако я захожу в бесконечный цикл, потому что тогда у меня нет возможности отобразить истинное значение при изменении поля критериев.

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);

ОБНОВЛЕНИЕ 2 с РЕШЕНИЕМ:

Я попробовал метод события preventDefault () при отправке, предложенный в комментариях, но это тоже не помогло. Я начал думать, что проблема может быть где-то в другом месте, за пределами компонента, поскольку состояние явно было сброшено при отправке (форма отправки не вызывала сброса).

Я начал изучать постоянство React Router и Store и решил дважды проверить реализацию Redux.

Мой index.js был таким:

<Provider store={store}>
    <App />
</Provider>

в то время как внутри App.js мой <BrowserRouter> был обернут вокруг компонента <Aux>. Как только я переместил <BrowserRouter> прямо под <Provider>, проблема сброса исчезла, и теперь все работает так, как должно.

Итак, мой index.js теперь

<Provider store={store}>
    <BrowserRouter>
        <App />
    </BrowserRouter>
</Provider>

person Greg Wozniak    schedule 13.04.2018    source источник


Ответы (2)


Хотя мне никогда не приходилось сохранять локальное состояние после отправки формы, такое поведение кажется довольно странным. Не могли бы вы использовать preventDefault для метода обработки формы, чтобы предотвратить перезагрузку страницы после отправки?

Дай мне знать, если это работает.

person Nnanyielugo    schedule 13.04.2018
comment
Я пробовал это, но это не помогло. То же самое происходит, когда я просто нажимаю кнопку onClick. Как лучше всего передать мое локальное состояние в Редуктор? Можно ли сделать это через dispatch, передав его (или его часть) в качестве параметра? - person Greg Wozniak; 14.04.2018
comment
Я думаю, что передавать локальное состояние редуктору через отправку - это нормально. Обычно я создаю пустой объект, добавляю к нему части локального состояния, которые хочу, а затем отправляю объект редуктору в качестве параметра отправки. - person Nnanyielugo; 15.04.2018
comment
Можете ли вы показать код компонента, где сбрасывается локальное состояние? Дайте мне посмотреть, смогу ли я воссоздать проблему (и, возможно, решение) - person Nnanyielugo; 15.04.2018

Не похоже, что вы предотвратили стандартное поведение перезагрузки формы (учитывая, что вы помещаете обработчик отправки в форму, а не на кнопку. Вот что вы должны попробовать: создать метод отправки перед методом визуализации. Этот метод должен принимать параметр «событие», который затем вызовет метод предотвращения по умолчанию перед вызовом методов для отправки данных формы в хранилище.

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

Вместо этого метод OnSubmit вашей формы должен вызывать критерийSubmission.

person Nnanyielugo    schedule 16.04.2018
comment
Это правда, и это, вероятно, останавливает сброс формы, вы правы, но все значения уже находятся в состоянии редуктора, и я предпочитаю отправлять их при нажатии, а не при изменении. Я пытаюсь найти здесь правильный шаблон дизайна. - person Greg Wozniak; 16.04.2018
comment
Я поместил туда метод для события onSubmit формы, а не для события onChange входного элемента. Вы по-прежнему отправляете их по клику. - person Nnanyielugo; 16.04.2018