反应路由器状态?

时间:2020-09-26 11:00:50

标签: javascript reactjs react-router

我有一个simple code here。我正在使用react-router,但我不明白为什么所有页面的状态都固定为初始渲染之一,而inputfields共享所有值?

import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Page from "./Page";

export default function App() {
  return (
    <Router>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/users">Users</Link>

      <Switch>
        <Route path="/about">
          <Page direction="left" />
        </Route>
        <Route path="/users">
          <Page direction="right" />
        </Route>
        <Route path="/">
          <Page direction="up" />
        </Route>
      </Switch>
    </Router>
  );
}

import React, { useReducer } from "react";

export default function Page({direction}){
  let reducer = (state, action) => state;
  let [state, dispatch] = useReducer(reducer, {direction});
  return (<div><input type="text"/>{state.direction}</div>)
}

3 个答案:

答案 0 :(得分:3)

尽管other answer提供了解决方案,但我认为它缺少对问题原因的解释。

问题:

因此,问题在于React如何以一种优化的方式更新UI。就您而言,React正在重新使用您的Page组件。因为Page组件已经在DOM中,所以没有创建一个新组件,React重用了Page组件的相同实例,仅更改了已更改的数据,在您的情况下,仅更改了{ {1}}道具更改。

添加direction道具是可行的,因为这使React能够区分key组件的不同实例。

替代解决方案:

React重用Page组件时,Page组件的剩余实例保持不变,但将不同的Page传递给基础实例。

在您的代码中,由于props属性更改时不会更新状态,因此看不到其他状态值。

要解决此问题,您可以使用direction钩子,该钩子会在useEffect道具更改时调度动作以更新状态。

按如下所示更改direction文件中的代码将解决此问题:

Page.js

有关更多详细信息,请参见:React - Reconciliation

答案 1 :(得分:2)

您可以通过在每个key组件中添加属性Page来解决此问题

<Switch>
  <Route  path="/about">
    <Page key="/about" direction="left" />
  </Route>
  <Route path="/users">
    <Page key="/users"  direction="right" />
  </Route>
  <Route  path="/">
    <Page key="/" direction="up" />
  </Route>
</Switch>;

这样,您将利用差异算法https://reactjs.org/docs/reconciliation.html#keys

答案 2 :(得分:0)

这适用于您的Page组件:

import React from "react";

export default function Page(props) {

  return (
    <div>
      <input type="text" />
      {JSON.stringify(props)}
    </div>
  );
}