【问题标题】:React router state?反应路由器状态?
【发布时间】:2020-09-26 11:00:50
【问题描述】:

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

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

【问题讨论】:

  • 给定链接上的代码不起作用

标签: javascript reactjs react-router


【解决方案1】:

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

问题:

所以问题在于 React 如何以优化的方式更新 UI。在您的情况下,React 正在重新使用您的 Page 组件。因为 Page 组件已经在 DOM 中,而不是创建一个新组件,React 重新使用 Page 组件的相同实例并且只更改已更改的数据,在您的情况下,只有 direction 道具更改.

添加 key 属性有效,因为这允许 React 区分 Page 组件的不同实例。

替代方案:

当 React 重用 Page 组件时,Page 组件的底层实例保持不变,但不同的 props 被传递给底层实例。

在您的代码中,由于 direction 属性更改时您没有更新状态,因此您看不到不同的状态值。

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

如下所示更改Page.js文件中的代码将解决问题:

function reducer(state, action) {
  switch (action.type) {
    case "DIRECTION_CHANGE":
      return { ...state, direction: action.payload };
    default:
      return state;
  }
}

export default function Page({ direction }) {
  const [state, dispatch] = useReducer(reducer, { direction });

  useEffect(() => {
    dispatch({ type: "DIRECTION_CHANGE", payload: direction });
  }, [direction]);

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

更多详情请见:React - Reconciliation

【讨论】:

    【解决方案2】:

    您可以通过向每个 Page 组件添加属性 key 来修复它

    <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

    【讨论】:

    • 奇怪的行为,我在想 react 会自动执行此操作。好的,谢谢。
    【解决方案3】:

    这适用于您的页面组件:

    import React from "react";
    
    export default function Page(props) {
    
      return (
        <div>
          <input type="text" />
          {JSON.stringify(props)}
        </div>
      );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-08
      • 2018-12-14
      • 2021-02-05
      • 2018-01-05
      • 2016-07-03
      • 2017-01-30
      • 1970-01-01
      相关资源
      最近更新 更多