防止react-router history.push重新加载当前路由

时间:2016-06-18 12:19:37

标签: javascript reactjs react-router

我在react-router采取了我的第一步。

我目前正在使用hashHistory进行开发,而且我正在执行手册'导航。也就是说,我使用Link并且我正在调用history.push('/some/route');以便导航(响应对锚标记的普通旧点击) )。

我注意到的是,即使我已经在目标路线上,react-router每次调用history.push('/target/route');时都会重新渲染相关的目标组件:每push('/target/route')

  • 网址的片段部分仍为#/target/route
  • 网址的查询字符串部分更改为?_k=somethingRandom
  • 目标组件重新呈现

我希望重新渲染到而不是 - 当我已经在我的路线上时,我实际上期望history.push成为无操作; m试图push

我显然错过了一些东西,因为这不是正在发生的事情。有趣的是,我看到那些试图实现我想要摆脱的行为的人的帖子 - 他们想要刷新&# 39;可以这么说,没有离开它的路线。这看起来很像相反的问题:)。

你能否告诉我这是什么?我是误会,以及我将如何达到理想的行为?如果(当)切换到browserHistory时,这可能会消失吗?

6 个答案:

答案 0 :(得分:8)

我的猜测是您的组件重新渲染,因为当您推送路由器时,prop中的某些内容会发生变化。我怀疑它可能是action的{​​{1}}或key属性。您始终可以在每次渲染期间检查prop.location的所有值,以查看更改。

您可以通过将旧路径路径与prop生命周期方法中的新路径路径进行比较来解决此问题。如果它没有改变,你就在同一条路线上,你可以通过返回shouldComponentUpdate来阻止重新渲染。在所有其他情况下,请返回false。默认情况下,它始终返回true。

true

您还必须进行进一步检查,这样也会阻止您的组件更新组件中的shouldComponentUpdate: function(nextProps, nextState) { if(this.props.route.path == nextProps.route.path) return false; return true; } 更新,但我想这将是您的起点。

在官方react docs页面上详细了解state

  

当您确定转换到新道具和状态不需要更新组件时,请将此作为返回false的机会。

答案 1 :(得分:0)

我会试一试......

如果你降落在这里并希望更改你的网址(例如为了分享目的),那么RR docs已经有了所描述的解决方案。只需确保您不使用组件中的历史记录(即$delete = $stmt->execute(array('cat_id' =>$catid)); ),因为您将(按预期)路由到目标。但是,您可以访问this.props.history.push()浏览器历史记录,而不会干扰组件的your

仅在Chrome上测试

history

然后从您的XYZ组件

// history.js
import { createBrowserHistory } from 'history'
export default createBrowserHistory()

希望它可以帮助别人。

答案 2 :(得分:0)

CommandParameter中:

select b.recipeuuid
      ,b.proditemuuid
      ,b.proditemvalueuuid
  into #rectemp
  from rec_recipe as a
       inner join rec_recipevalue as b
               on b.recipeuuid=a.recipeuuid
              and b.[value] in ('Green','Yellow')
       inner join rec_proditem as c
               on c.proditemuuid=b.proditemuuid
       inner join rec_proditemvalue as d
               on d.proditemuuid=c.proditemuuid
              and d.proditemvalueuuid=b.proditemvalueuuid
              and d.[name]='SetupType'
;
***#rectemp is a temp table. Data imported into the table***
update a
   set a.[value]='1'
  from rec_recipevalue as a
       inner join #rectemp as b
               on b.recipeuuid=a.recipeuuid
              and b.proditemuuid=a.proditemuuid
              and b.proditemvalueuuid=a.proditemvalueuuid
 where a.[value] in ('Green','Yellow')
;
  ***Column Value is updated to 1 based on Value is Green or yellow***
update a
   set a.[name]='Normal'
  from rec_proditemvalue as a
       inner join #rectemp as b
               on b.proditemuuid=a.proditemuuid
              and b.proditemvalueuuid=a.proditemvalueuuid
 where a.[name]='SetupType'
;
  *** Name column is updated to Normal ***
drop table #rectemp;
  *** Temp Table is dropped***

答案 3 :(得分:0)

我遇到了同样的问题,并且找到了(愚蠢的)解决方案。

您只有tic("unnest") tib2 <- tib %>% tidyr::unnest(tib_df) %>% group_by(id) %>% top_n(1, num) %>% mutate(result = stringi::stri_sub(ch, length = 5)) toc(log = T, quiet = T) (默认情况下为> tic.log(format = T) [[1]] [1] "purrr: 39.54 sec elapsed" [[2]] [1] "setDT w key: 10.7 sec elapsed" [[3]] [1] "dt w key: 19.19 sec elapsed" [[4]] [1] "unnest: 1.62 sec elapsed" )或类似内容(表单,提交...等),它们像html tic("unnest+reattach") tib2 <- tib %>% tidyr::unnest(tib_df) %>% group_by(id) %>% top_n(1, num) %>% mutate(result = stringi::stri_sub(ch, length = 5)) tib3 <- tib %>% mutate(result = tib2$result[match(id, tib2$id)]) toc(log = T, quiet = T) tic.log(format = T)[[5]] [1] "unnest+reattach: 1.83 sec elapsed" 一样重新加载页面。

在您的代码中检查它,然后将其删除。

PD: <button>>这只是您要以表单发送的值输入(或按钮)。

答案 4 :(得分:0)

tsx样本

import {createBrowserHistory} from 'history';  
export const history = createBrowserHistory();


ReactDOM.render(
  <Router history={history}>
    <App/>
  </Router>,
  document.getElementById("root")
);

答案 5 :(得分:0)

我认为更简单的解决方法可能是用我们自己的路线替换路线

import { Route, withRouter } from "react-router-dom";

function MyRoute({ key, path, exact, component: Component, history }) {
  let lastLocation = null;
  return (
    <Route
      key={key}
      path={path}
      exact={exact}
      render={(props) => {
        history.listen((location) => {
          lastLocation = location;
        });

        // monkey patching to prevent pushing same url into history stack
        const prevHistoryPush = history.push;
        history.push = (pathname, state = {}) => {
          if (
            lastLocation === null ||
            pathname !==
              lastLocation.pathname + lastLocation.search + lastLocation.hash ||
            JSON.stringify(state) !== JSON.stringify(lastLocation.state)
          ) {
            prevHistoryPush(pathname, state);
          }
        };
        return <Component {...props} />;
      }}
    />
  );
}

export default withRouter(MyRoute);

我们使用它作为 react-router-dom 实际路由的包装器,它对我来说非常有效。 更多信息请参考here