Redux - ReactJS приложение не выполняет повторную визуализацию (хотя JSON .parse для нового объекта) - PullRequest
9 голосов
/ 26 мая 2020

У меня есть приложение ReactJS с фильтрами, и я использую функцию RESET для сброса этих фильтров.

Что я также использую: Redux, Redux Persist и React-router-dom.

Если я посмотрю на Redux Devtools, похоже, он работает. Но приложение не выполняет повторную визуализацию правильно, требуется refre sh (f5).

Чего я хочу добиться: переопределить объект configureFilters с помощью объекта initialState.

Это мой root редуктор:

const rootReducer = (state = initialState, action) => {
  let newState = state;
  if (action.type === 'RESET_FILTERS') {
    storage.removeItem('persist:configuredFilters');
    // eslint-disable-next-line no-param-reassign
    newState = { ...newState,
      configuredFilters: JSON.parse(JSON.stringify(initialState.configuredFilters))
    };
  }
  return appReducer(newState, action);
};

Вот разница (я настроил две страны раньше):

Diff after the RESET action has been called

Вот объект (начальный статус, если страница загружена):

The redux object configuredFilters

Компоненты создаются с помощью этого компонента:

/* eslint-disable max-len */
import React from 'react';
import { useSelector, shallowEqual, useDispatch } from 'react-redux';
import { Form, Select } from 'antd';
import PropTypes from 'prop-types';
import RenderTag from './RenderTag';
import * as Action from '../../store/configuredFilters/actions';

const propTypes = {
  data: PropTypes.shape({
    name: PropTypes.string.isRequired,
    label: PropTypes.string,
    placeholder: PropTypes.string,
    options: PropTypes.arrayOf(PropTypes.shape({})),
  }).isRequired,
};


const { Option } = Select;


const useData = () => {
  const dataFromRdx = useSelector(
    (state) => ({
      configuredFilters: state.configuredFilters,
    }),
    shallowEqual
  );
  return { dataFromRdx };
};

const FixedListSelect = ({
  data: {
    name, label, placeholder, options,
  },
}) => {
  const { dataFromRdx } = useData();

  const {
    configuredFilters: {
      data: {
        search: searchTerm,
      },
    },
  } = dataFromRdx;


  const dispatch = useDispatch();
  const dispatchFns = {
    setConfiguredFilters: (key, value) => {
      dispatch(Action.setConfiguredFilters(key, value));
    },
  };

  const setRdxVal = (id, currVal) => {
    dispatchFns.setConfiguredFilters(id, currVal);
  };

  const isFullTextSearchMode = (searchTerm && searchTerm.length);
  return (
    <Form.Item
      name={name}
      label={label}
      fieldKey={name}
    >
      <Select
        allowClear
        disabled={isFullTextSearchMode}
        showSearch
        tagRender={RenderTag}
        mode="multiple"
        placeholder={placeholder}
        optionFilterProp="children"
        filterOption={(input, option) => option.children.toLowerCase().includes(input.toLowerCase())}
        onChange={(currVal) => { setRdxVal(name, currVal); }}
      >
        {(options || []).map((el) => <Option data-filterid={el.val} key={el.val} value={el.val}>{el.label}</Option>)}
      </Select>
    </Form.Item>
  );
};
FixedListSelect.propTypes = propTypes;
export default FixedListSelect;

Вызов этого компонента:

<FixedListSelect data={{
          name: 'companies',
          label: t('companies'),
          placeholder: t('companies-placeholder'),
          options: companies,
        }}
        />

Может кто-нибудь поможет или хотя бы подскажет?

Ответы [ 2 ]

0 голосов
/ 09 июня 2020

В ReactJS вы не можете напрямую изменять состояние. То же самое и в Redux. Вы должны скопировать существующую информацию. Redux сравнивает текущее дерево с новой информацией, если обнаруживает разницу, обновляет хранилище и отображает новый результат. Если мутировать напрямую, вы всегда будете обновлять sh, чтобы он работал.

Подробнее

Неизменяемые шаблоны обновления

0 голосов
/ 26 мая 2020

Я не вижу, чтобы вы передали configureFilters в качестве опоры для вашего компонента, см. { ссылка } для ответа. Из связанного ответа: «Ваш компонент будет повторно визуализироваться только в том случае, если его состояние или свойства изменены». В вашем компоненте вы просто берете состояние с помощью useSelector из хранилища redux. Вы можете решить свою проблему, используя mapStateToProps: https://react-redux.js.org/using-react-redux/connect-mapstate.

...