首页 > 解决方案 > 反应路由器状态?

问题描述

这里有一个简单的代码。我正在使用 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>)
}

标签: javascriptreactjsreact-router

解决方案


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

问题:

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

添加keyprop 是可行的,因为这允许 React 区分Page组件的不同实例。

替代解决方案:

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

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

为了解决这个问题,你可以使用useEffect钩子来调度一个动作,以便在directionprop 更改时更新状态。

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


推荐阅读