如何在react js中保留浏览器后退按钮上应用的过滤器

IT技术 javascript reactjs react-native react-router react-redux
2021-05-11 20:46:41

在我的应用程序中,所有列表页面上都有过滤器。现在根据要求,我想在浏览器后退按钮上保留应用的过滤器。例如,说用户在销售列表页面上应用了过滤器。之后,他点击一条记录进入销售编辑页面。现在,如果用户点击浏览器后退按钮,那么那些应用的过滤器应该保留。为了做到这一点,我喜欢下面。在销售列表页面上,

  componentWillMount() {
  const { list, checkReportClose, 
    updateReportCloseStatus } = this.props;
   const { inPopState } = this.state;
    window.onpopstate = () => {
    if (!_.isEmpty(list)) {
     this.setState({ filters: JSON.parse(list.input.filters), 
       inPopState: true}, this.loadList);
    }
   }
   if(!inPopState && inPopState != undefined && 
   checkReportClose == false) {
     this.loadList();
   }
   }

使用上面的代码它工作正常,但是当返回按钮时它会调用 lis 页面 api (this.loadList) twise。

请提出一些新的解决方案或对现有解决方案的修改。

谢谢。

1个回答

我建议使用 url 将过滤器存储为参数。

我在下面写了一个例子。让我们http://skylerfenn.com/news?order=asc&category=feature&year=2017用作以下函数的 url。

第1步:呼叫getParameters()window.onpopstate和参数存储在状态。使用上面的 URL,getParameters()将参数作为对象返回{ order: 'asc', category: 'feature', year: '2017' }

function getParameters() {
  let parameters = window.location.search.replace('?', '');

  let currentParameters = {};

  if (Object.keys(parameters).length) {

    parameters = parameters.split('&');

    for (let i = 0; i < parameters.length; i++) {
      let parameter = parameters[i].split('=');
      currentParameters[parameter[0]] = parameter[1];
    }

  }

  return currentParameters;
}

第 2 步:将任何新参数getNewParameters作为对象传递给下面函数。例如,调用getNewParameters({ order: 'desc', year: null })返回对象{ order: 'desc', category: 'feature' }请注意,它删除了年份,因为它为空。

function getNewParameters(newParameters) {
  const parameters = getParameters();

  const keys = Object.keys(newParameters);

  for (let i = 0; i < keys.length; i++) {
    const value = newParameters[keys[i]];

    parameters[keys[i]] = value;

    if (!value) {
      delete parameters[keys[i]];
    }
  }

  return parameters;
}

第 3 步:使用结果getNewParameters更新状态。还将结果传递给下面的函数以更新您的网址。

updateUrl(parameters) {
  let search = '';
  let j = 0;
  let separator = '?';

  Object.keys(parameters).forEach((key) => {

    let value = parameters[key];

    if (value) {

      if (j !== 0) {
        separator = '&';
      }

      search += `${separator}${key}=${value}`;

      j++;
    }
  });

  let newUrl = `${location.origin}${location.pathname}${search}`;

  // prevents pushing same url if function won't change url.
  if (location.href !== newUrl) {
    history.pushState(null, null, newUrl);
  }
}