Я создаю изоморфное приложение React. Рабочий процесс Сейчас я работаю через это:Реакция на вызов при каждом изменении
- Пользователь переходит на
/questions
маршрут, который делает на стороне сервера API вызова и загружает данные на этой странице. Это вызывает функциюrenderData()
, как она должна, и загружает все вопросы, которые пользователь видит. - Пользователь нажимает кнопку добавления, чтобы добавить новый вопрос, и модальные всплывающие окна для ввода пользователем полей формы и создания нового вопроса.
С каждым изменением модальности функция renderData()
получает вызов (что не должно). Когда пользователь нажимает кнопку Create Question
, функция renderData()
также получает вызов - это ошибка, потому что состояние изменяется.
Я не могу точно определить, почему функция renderData()
вызывается каждый раз, когда что-то происходит в модальном режиме. Любые идеи относительно того, почему это происходит и как его избежать?
Основной компонент:
import React, { Component, PropTypes } from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './QuestionsPage.scss';
import QuestionStore from '../../stores/QuestionStore';
import QuestionActions from '../../actions/QuestionActions';
import Loader from 'react-loader';
import QuestionItem from '../../components/QuestionsPage/QuestionItem';
import FloatButton from '../../components/UI/FloatButton';
import AddQuestionModal from '../../components/QuestionsPage/AddQuestionModal';
const title = 'Questions';
class QuestionsPage extends Component {
constructor(props) {
super(props);
this.state = QuestionStore.getState();
this.onChange = this.onChange.bind(this);
this.openModal = this.openModal.bind(this);
this.closeMOdal = this.closeModal.bind(this);
}
static contextTypes = {
onSetTitle: PropTypes.func.isRequired,
};
componentWillMount() {
this.context.onSetTitle(title);
QuestionStore.listen(this.onChange);
}
componentWillUnmount() {
QuestionStore.unlisten(this.onChange);
}
onChange(state) {
this.setState(state);
}
openModal =() => {
this.setState({ modalIsOpen: true});
}
closeModal =() => {
this.setState({ modalIsOpen: false});
}
createQuestion =() => {
const date = new Date();
const q = this.state.question;
q.createdAt = date;
this.setState({ question : q });
QuestionStore.createQuestion(this.state.question);
}
textChange = (val) => {
const q = this.state.question;
q.text = val;
this.setState({ question : q });
}
answerChange = (val) => {
const q = this.state.question;
q.answer = val;
this.setState({ question : q });
}
tagChange = (val) => {
const q = this.state.question;
q.tag = val;
this.setState({ question : q });
}
companyChange = (val) => {
const q = this.state.question;
q.company = val;
this.setState({ question : q });
}
renderData() {
return this.state.data.map((data) => {
return (
<QuestionItem key={data.id} data={data} />
)
})
}
render() {
return (
<div className={s.root}>
<div className={s.container}>
<h1>{title}</h1>
<div>
<Loader loaded={this.state.loaded} />
<FloatButton openModal={this.openModal}/>
<AddQuestionModal
open = {this.state.modalIsOpen}
close = {this.closeModal}
createQuestion = {this.createQuestion}
changeText = {this.textChange}
changeAnswer = {this.answerChange}
changeTag = {this.tagChange}
changeCompany = {this.companyChange}
/>
{ this.renderData() }
</div>
</div>
</div>
);
}
}
export default withStyles(QuestionsPage, s);
модальный компонент:
import React, { Component, PropTypes } from 'react';
import QuestionStore from '../../stores/QuestionStore';
import QuestionActions from '../../actions/QuestionActions';
import Modal from 'react-modal';
import TextInput from '../UI/TextInput';
import Button from '../UI/Button';
class AddQuestionModal extends Component {
createQuestion =() => {
this.props.createQuestion();
}
closeModal =() => {
this.props.close();
}
changeText = (val) => {
this.props.changeText(val);
}
changeAnswer = (val) => {
this.props.changeAnswer(val);
}
changeTag = (val) => {
this.props.changeTag(val);
}
changeCompany = (val) => {
this.props.changeCompany(val);
}
render() {
return (
<Modal
isOpen={this.props.open}
onRequestClose={this.closeModal} >
<TextInput
hintText="Question"
change={this.changeText} />
<TextInput
hintText="Answer"
change={this.changeAnswer} />
<TextInput
hintText="Tag"
change={this.changeTag} />
<TextInput
hintText="Company"
change={this.changeCompany} />
<Button label="Create Question" onSubmit={this.createQuestion} disabled={false}/>
<Button label="Cancel" onSubmit={this.closeModal} disabled={false}/>
</Modal>
);
}
}
export default AddQuestionModal;
На щелчку
Поскольку ваш метод renderData() 'вызывается в рендере, любое изменение состояния на' QuestionsPage' приведет к его срабатыванию. Ваше прослушивание вашего магазина, а затем в каждом магазине обновит ваш 'onChange', всегда будет срабатывать. Ваша кнопка вызывает его prop 'createQuestion', который затем вызывает ваш магазин' QuestionStore', который затем перезапускает цикл рендеринга. Вам нужна логика внутри вашего onChange, чтобы остановить 'setState', если он не нужен. – enjoylife