Мне нужен компонент для проверки состояния и повторного рендеринга после изменения другого компонента (используя React Hooks) - PullRequest
0 голосов
/ 25 марта 2020

Я не уверен, что то, что я спрашиваю, даже возможно, но здесь идет. У меня есть веб-приложение с несколькими компонентами, двумя из которых являются панель фильтров и отображение фильтра. Нам пришлось провести серьезный рефакторинг панели фильтров и изменить его с компонента класса на функциональный компонент с хуками, и мне пришлось включить некоторый код forceUpdate, чтобы панель фильтров фактически показывала значения фильтра, которые были выбраны (т. Е. Щелчок по фильтру). Выбор на панели фильтров изменил бы отображение панели, но не изменил саму панель фильтров, если вы не закрыли и не открыли ее снова). Компонент отображения фильтра представляет собой простую панель расширения, которая по умолчанию открыта и показывает фильтры, которые в данный момент активны. Ранее он обновлялся автоматически при изменении значения на панели фильтров, но поскольку я переписал панель фильтров, он будет обновляться только в случае закрытия и повторного открытия панели расширения. Вот некоторый код в отображении фильтра:

const FilterDisplay = props => {
const [expanded, setExpanded] = useState("panel1");
const selectionFilters = useSelector(state => state.fetchFilter);
const availableFilters = useSelector(state => state.fetchFilterSelect);
const viz = useSelector(state => state.fetchDashboard);

const handleChange = panel => (event, isExpanded) => {
setExpanded(isExpanded ? panel : false);
};

return (
<div className={classes.rootPanel}>
  <MuiExpansionPanel
    expanded={expanded === "panel1"}
    onChange={handleChange("panel1")}
  >
    <MuiExpansionPanelSummary
      expandIcon={<ExpandMoreIcon edge="start" />}
    >
      <Typography variant="subtitle" className={classes.headingPanel}>
        Show Applied Filters
      </Typography>
    </MuiExpansionPanelSummary>

    {Object.keys(selectionFilters)
        .filter(key => {
          return (
            availableFilters[key] !== undefined &&
            availableFilters[key].length > 0 &&
            selectionFilters[key].length !==
            availableFilters[key].length 
          );
        })
        .map(title => {
          return (
            <MuiExpansionPanelDetails
              key={title}
              className={classes.ExpansionPanelD}
            >
              <Typography className={classes.filterTitle} variant="p">
                {title}
                {"  :  "}
              </Typography>

              {selectionFilters[title].length < 10 ? (
                selectionFilters[title].map(value => {
                  return (
                    <span key={value} className={classes.filterValue}>
                      <Chip
                        label={value}//this is the value that needs to change when the filterbar changes
                      />
                    </span>
                  );
                })
              ) : (
                  <Typography variant="p" className={classes.selection}>
                    {selectionFilters[title].length} selected
                  </Typography>
                )}
            </MuiExpansionPanelDetails>
          );
        })}
  </MuiExpansionPanel>
</div>
);
};

export default FilterDisplay;

Я бы запрограммировал forceUpdate, но я не могу понять, как это сделать, не вызывая неограниченное количество повторений (в отличие от панели фильтров, где я хочу, чтобы изменить, когда пользователь специально что-то делает на панели фильтров, мне нужно обновить отображение фильтра, не когда кто-то открывает или закрывает отображение фильтра, а когда они что-то меняют на панели фильтров). Кто-нибудь может дать мне несколько идей? ТИА!

Ответы [ 2 ]

0 голосов
/ 25 марта 2020

Хорошо, я нашел решение, которое не заставляет его перерисовываться, как только меняется панель фильтров, но вызывает перерисовку, когда панель фильтров закрывается. По сути, сразу после функции handleChange я добавил этот небольшой блок кода:

if (props.drawerOpen) {
console.log(props.selectionFilters)
};

Таким образом, в основном, пользователь откроет панель фильтров, внесет изменения, закроет панель фильтров, и дисплей фильтра обновится с изменениями .

0 голосов
/ 25 марта 2020

Похоже, что вы используете useSelector() из Reaction-Redux для получения ваших selectionFilters. Из документов :

Когда компонент функции рендерится, будет вызвана предоставленная функция селектора, и ее результат будет возвращен из ловушки useSelector (). [...] useSelector () вызывает принудительную повторную визуализацию, только если результат селектора отличается от последнего результата. Начиная с v7.1.0-alpha.5, сравнение по умолчанию является строгим === сравнительным сравнением .

useSelector() получает в качестве второго аргумента обратный вызов, в котором вы можете выполнить сравнение самостоятельно. В документах они рекомендуют использовать shallowEqual, который они экспортируют в Reaction-redux:

import { shallowEqual, useSelector } from 'react-redux'
// ...

const selectionFilters = useSelector(state => state.fetchFilter, shallowEqual);

Вы, конечно, можете предоставить функцию сравнения, если она не работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...