我有条件地渲染组件(屏幕)作为用户将被引导通过不同的屏幕。我正在尝试实现一个功能,用户可以使用浏览器的后退和前进按钮,在这些不同的屏幕或组件之间导航。我正在努力实现这一点。任何建议都将不胜感激。
链接到沙箱:https://codesandbox.io/s/history-push-and-pop-state-listening-forked-1keiz?file=/src/App.js
const [show1, setShow1] = useState(true);
const [show2, setShow2] = useState(false);
const [show3, setShow3] = useState(false);
let stateForHistory = {
show1: false,
show2: false,
show3: false
};
const handleClick = () => {
setShow1(false);
setShow2(true);
if(show2)
setShow2(false)
setShow3(true)
};
//saving state onmount
useEffect(() => {
window.history.pushState(stateForHistory, "", "");
}, []);
useEffect(() => {
window.addEventListener("popstate", (e) => {
let { show1, show2, show3 } = e.state || {};
if (!show1 && show2) {
setShow1(true);
setShow2(false);
}
});
return () => {
window.removeEventListener("popstate", null);
};
});
return (
<div className="App">
<div id="screen-1">
{show1 && <Screen1 />}
</div>
<div id="screen-2">
{show2 && <Screen2 />}
</div>
<div id="screen-3">
{show3 && <Screen3 />}
</div>
<button onClick={handleClick} id="btn">
Next
</button>
</div>
);
}发布于 2021-08-24 23:38:08
我建议使用路由包来处理导航方面,您的代码可以集中在屏幕上。你所描述的听起来像是一台步进机。
索引
将App包装在路由器中。
import ReactDOM from "react-dom";
import { BrowserRouter as Router } from "react-router-dom";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<Router>
<App />
</Router>,
rootElement
);应用程序
定义带有路径参数的路由,以匹配“步骤”或屏幕。
function App() {
return (
<div className="App">
<Switch>
<Route path="/step/:step">
<Stepper />
</Route>
<Redirect to="/step/1" />
</Switch>
</div>
);
}创建一个screen stepper组件来监听路由中的更改,特别是对step参数的更改,并有条件地呈现屏幕。
const ScreenStepper = () => {
const history = useHistory();
const { step } = useParams();
const { path } = useRouteMatch();
const nextStep = (next) => () =>
history.push(generatePath(path, { step: Number(step) + next }));
const renderStep = (step) => {
switch (step) {
case 3:
return <Screen3 />;
case 2:
return <Screen2 />;
case 1:
return <Screen1 />;
default:
}
};
return (
<>
<h1>Step: {step}</h1>
{renderStep(Number(step))}
<button disabled={Number(step) === 1} onClick={nextStep(-1)} id="btn">
Previous
</button>
<button onClick={nextStep(1)} id="btn">
Next
</button>
</>
);
};您可以在此基础上进行扩展/自定义,以限制屏幕数量,或者从数组渲染屏幕路由,等等。
https://stackoverflow.com/questions/68914775
复制相似问题