首页 > 解决方案 > Redux - ReactJS 应用程序不会重新渲染(尽管 JSON.parse 用于新对象)

问题描述

我有一个带有过滤器的 ReactJS 应用程序,并使用 RESET 函数来重置这些过滤器。

我还使用:Redux、Redux Persist 和 React-router-dom。

如果我看一下 Redux Devtools,它似乎可以工作。但应用程序无法正确重新渲染,需要刷新 (f5)。

我想要实现的目标:用 initialState 对象覆盖已配置的Filters 对象。

这是我的根减速器:

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);
};

这是差异(我之前配置了两个国家):

调用 RESET 操作后的差异

这是对象(如果页面已加载,则为初始状态):

redux 对象配置的Filters

使用此组件创建组件:

/* 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,
        }}
        />

有人可以提供帮助或至少给出提示吗?

标签: javascriptreactjsreducers

解决方案


在 ReactJS 中,你不能直接改变状态。在 Redux 中也是如此。您必须复制现有信息。如果发现差异,Redux 会将当前树与新信息进行比较,然后更新存储并呈现新结果。如果直接变异,您将始终刷新以使其正常工作。

更多信息

不可变的更新模式


推荐阅读