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