Почему изменение в магазине props / redux не вызывает обновление во втором экземпляре? - PullRequest
0 голосов
/ 14 апреля 2020

Я работаю со следующим подключенным компонентом.

Содержит два раскрывающихся списка; родитель и ребенок. Когда родительский раскрывающийся список изменяется, он заполняет дочерний раскрывающийся список.

Параметры раскрывающегося списка извлекаются из API в родительском компоненте и сохраняются в хранилище Redux.

При первом отображении компонента, опция по умолчанию 'TELEVISION (T)' должна быть выбрана в раскрывающемся списке родителя и 'TV' в дочернем фильтре.

У меня есть два экземпляра компонента. Когда раскрывающиеся значения изменяются в одном экземпляре, это должно быть реплицировано в другом экземпляре. Это работает, как и ожидалось, с раскрывающимся списком родителей, но не с раскрывающимся списком дочерних элементов.

Примите во внимание любые советы о том, что мне нужно изменить, чтобы синхронизировать c выбранную дочернюю опцию в обоих случаях.

import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { Dropdown } from 'semantic-ui-react';
import {
  changeParent,
  changeChild
} from '../../actions/menuFiltersActions';
import makeDropdownOptions from '../../lib/makeDropdownOptions';


export class ParentChildFilter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      children: []
    };

    this.TELEVISION = 'TELEVISION';
    this.TV = 'TV';
    this.changeParent = this.changeParent.bind(this);
    this.changeChild = this.changeChild.bind(this);
  }

  componentDidMount() {
    if (this.props.parentChild.data.length) {
      // eslint-disable-next-line
      const { parentId, childId } = this.parentChildId();
      this.changeParent(parentId);
    }
  }

  componentDidUpdate(prevProps) {
    if (prevProps.parentChild.data !== this.props.parentChild.data) {
      // eslint-disable-next-line
      const {parentId, childId} = this.parentChildId();
      this.changeParent(parentId);
    }
  }

  /**
   * Find the parentChild id for TELEVISION and booking id for TV.
   */
  parentChildId() {
    const tvMedia = this.props.parentChild.data.find(m => m.name.indexOf(this.TELEVISION) !== -1);
    const parentId = tvMedia && 'id' in tvMedia ? tvMedia.id : this.props.parentChild.data[0].id;

    const tvBooking = this.props.parentChild.data.find(
      m => m.id === parentId
    ).children.find(b => b.name === this.TV);

    const childId = tvBooking && 'id' in tvBooking ? tvBooking.id : this.props.parentChild.data.find(
      m => m.id === parentId
    ).children[0].id;

    return { parentId, childId };
  }

  /**
   * When a user selects a Parent from a filter display the associated children.
   * When a user selects Parent TELEVISION, display Booking TV as default.
   * @param {*} id integer id of user selected Media.
   */
  changeParent(id) {
    // Get the TELEVISION Media id and TV Booking id.
    const { parentId, childId } = this.parentChildId();

    // Fetch the children associated with the selected Media id.
    const { children } = this.props.parentChild.data.find(m => m.id === id);

    // If the user is selecting TELEVISION Media, display TV booking by default.
    const wantedTvBookingId = id === parentId
      ? childId
      : this.props.parentChild.selectedBooking;

    let selectedBooking = children.find(b => (b.id === wantedTvBookingId));

    selectedBooking = selectedBooking
      ? selectedBooking.id
      : children[0].id;

    this.props.changeParent(id);
    this.setState({ children }, () => this.changeChild(selectedBooking));
  }

  changeChild(id) {
    this.props.changeChild(id);
  }


  render() {
    return (
      <>
        <span id="parentChild-label">Media Name</span>
        <Dropdown
          fluid
          selection
          loading={!this.props.parentChild.data.length}
          placeholder="Select a Media"
          options={makeDropdownOptions(this.props.parentChild.data, 'name', 'id')}
          value={this.props.parentChild.selectedMedia}
          onChange={(e, { value }) => this.changeParent(value)}
          aria-labelledby="parentChild-label"
        />

        <span id="booking-category-label">Booking Category</span>
        <Dropdown
          fluid
          selection
          loading={!this.state.children.length}
          placeholder="Select a Booking Category"
          options={makeDropdownOptions(this.state.children, 'name', 'id')}
          value={this.props.parentChild.selectedBooking}
          onChange={(e, { value }) => this.changeChild(value)}
          aria-labelledby="booking-category-label"
        />
      </>
    );
  }
}

ParentChildFilter.propTypes = {
  parentChild: PropTypes.exact({
    data: PropTypes.array,
    selectedMedia: PropTypes.number,
    selectedBooking: PropTypes.number
  }).isRequired,
  changeParent: PropTypes.func.isRequired,
  changeChild: PropTypes.func.isRequired
};

export default connect(
  store => ({
    parentChild: store.menuFilters.parentChild
  }),
  {
    changeParent,
    changeChild
  }
)(ParentChildFilter);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...