javascript - 反应路由器状态?
问题描述
我这里有一个简单的代码。我正在使用 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>)
}
解决方案
尽管其他答案提供了解决方案,但我认为它缺少对问题原因的解释。
问题:
所以问题在于 React 如何以优化的方式更新 UI。在您的情况下,React 正在重用您的Page
组件。因为Page
组件已经在 DOM 中,而不是创建一个新的,React 重用Page
组件的相同实例并且只更改已更改的数据,在您的情况下,只有direction
prop 更改。
添加key
prop 是可行的,因为这允许 React 区分Page
组件的不同实例。
替代解决方案:
当 React 重用Page
组件时,Page
组件的底层实例保持不变,但不同props
的实例被传递给底层实例。
在您的代码中,由于您没有在direction
prop 更改时更新状态,因此您看不到不同的状态值。
为了解决这个问题,你可以使用useEffect
钩子来调度一个动作,以便在direction
prop 更改时更新状态。
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
推荐阅读
- botframework - 机器人图标未更新
- python-3.x - 如何在 PySpark 数据框中为该列中存在的所有唯一值查找列的分布?
- talend - 是什么导致 Collibra 从 Collibra Connect 过渡?
- mysql - MySQL 8.0官方和Oracle Docker镜像的排序差异
- vue.js - 如何将活动类绑定到循环中的第一个元素
- c - 如何在不使用 GCC 中的limits.h 头文件的情况下编译C 程序?
- r - 更改 data.frame 的结构
- javascript - 如何使 UseEffect 挂钩逐步运行而不是持续运行?
- vue.js - 如何在 vuejs 的上下文中调整 vs-popup 的大小
- php - 使用未定义的根路径