Сценарий, с которым я столкнулся, есть массив заданий, сохраненных как состояние Redux. У меня есть контейнер, который обращается к данным с помощью соединителя Redux и использует параметр this.props.params, чтобы затем найти соответствующий Job, а затем передать его детям в качестве опоры.React, Redux: обновить состояние и повторно отобразить дочерние объекты
Внутри дочернего компонента задание запускает действие, которое обновляет задание, а затем объединяется и обновляет задания в хранилище. Кажется, что это работает нормально, но когда контейнер повторно отображает ребенка, нет. Я вижу, что это связано с тем, что я не храню работу как реквизит или состояние.
Мой вопрос - лучший способ (Redux) справиться с этим?
Поэтому, если я сменил JobShow на включение заданий = {jobs}, он повторно отображает по мере обновления заданий. Это, по-видимому, указывает на то, что состояние не мутирует, я также могу подтвердить, что сам контейнер повторно отображает и даже повторно запускает renderView(), но не повторно отображает JobShow.
Контейнер:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';
import JobShow from './job_show';
class JobContainer extends Component {
constructor(props){
super(props);
}
renderView(job, customer){
let viewParam = this.props.params.view;
switch(viewParam){
case "edit": return <JobEdit customer={customer} job={job}/>
case "notes": return <JobShow customer={customer} activeTab={"notes"} job={job}/>
case "quote": return <JobShow customer={customer} activeTab={"quote"} job={job}/>
case "invoice": return <JobShow customer={customer} activeTab={"invoice"} job={job}/>
default: return <JobShow customer={customer} activeTab={"notes"} job={job}/>
}
}
render() {
let { jobs, customers } = this.props;
if (jobs.length < 1 || customers.length < 1){
return <div>Loading...</div>;
}
let job = jobs.find(jobbie => jobbie.displayId == this.props.params.jobId);
let customer = customers.find(customer => customer._id.$oid == job.customers[0]);
return (
<div className="rhs">
{this.renderView(job, customer)}
</div>
);
}
}
JobContainer.contextTypes = {
router: React.PropTypes.object.isRequired
};
function mapStateToProps(state) {
return {
jobs: state.jobs.all,
customers: state.customers.all
};
}
export default connect(mapStateToProps, actions)(JobContainer);
Редуктор Отрывок:
import update from 'react-addons-update';
import _ from 'lodash';
export default function(state= INITIAL_STATE, action) {
switch (action.type) {
case FETCH_ALL_JOBS:
return { ...state, all: action.payload, fetched: true };
case UPDATE_JOB_STATUS:
let newStatusdata = action.payload;
let jobToUpdate = state.all.find(jobbie => jobbie.displayId == newStatusdata.displayId);
jobToUpdate.status = newStatusdata.newStatus;
jobToUpdate.modifiedAt = newStatusdata.timeModified;
let updatedJobIndex = _.indexOf(state.all, state.all.find(jobbie => jobbie.displayId == newStatusdata.displayId));
let updatedState = update(state.all, {$merge: {[updatedJobIndex]: jobToUpdate}});
return { ...state, all: updatedState}
Если ничего другого, похоже, вы мутируете свое состояние с помощью строк 'jobToUpdate.status = ....'. Случайная мутация почти всегда является причиной того, что компоненты не перерисовываются. См. Http://redux.js.org/docs/FAQ.html#react-not-rerendering. Кроме того, как выглядят работы и ваше начальное состояние? – markerikson
Итак, если я сменил JobShow на включение заданий = {jobs}, он повторно отображает по мере обновления заданий, но передача реквизита, который ребенок не нужен, кажется неправильным. Это, по-видимому, указывает на то, что состояние не мутирует, я также могу подтвердить, что сам контейнер повторно отображает и даже повторно запускает функцию renderView, но просто не перерисовывает JobShow. –
Поиск большего кода может помочь, но ваши строки 'jobToUpdate' в фрагменте редуктора напрямую мутируют этот объект задания, а не делают копию, только изменяя копию и возвращая эту копию. Так что да, если вы пытаетесь передать этот объект задания самому дочернему компоненту в качестве опоры, сама ссылка не изменилась, а дочерний компонент не будет обновляться. – markerikson