如何像应用程序一样在 React 中切换组件
How to Switch component in React like an app
我是 React 的初学者,我想制作一个带有仪表板的网络应用程序,如 Windows 磁贴。
我很容易生成它们。但我希望当我点击其中一个时,隐藏 Dash 菜单并显示子应用程序“Prog1”。当然,扭转它。当我单击关闭按钮时,它会关闭子应用程序并 returns 到 Dash 菜单(暗示它隐藏 Prog1 以显示 Dash)。
我可以用这样的函数隐藏 Dash 菜单:
fctHide = () => {
this.setState({ isActive: false });
}
但是我怎样才能显示另一个可能具有 fctShow 之类功能的子应用程序?
我们是被迫将函数放在 class 中还是只是制作一个通用的 display/hide 函数?
有没有更简单和更新的方法来做到这一点(例如使用钩子)。
我的应用在 Codepen 上:codepen
我可以按需在这里给你看。
我很惊讶地看到很多问题或教程显示和隐藏按钮中的元素而不是在 class/HTML/template 等之间切换(我猜像 React Native 路由器)。
谢谢!
除非您要将旧应用程序转换为 React,即不是从头开始编写纯 React 应用程序,否则不要多次使用 ReactDOM.render。由于您想在组件之间共享活动状态,因此它应该存在于它们的 closest common ancestor.
中
我不确定您的仪表板应该如何工作,但这里有一个 demo. Here, APP is such closest ancestor. You don't need react-router if you are not using URL routes or the History API。
import React from "react";
import "./styles.css";
class Dash extends React.Component {
render() {
const { isActive, fctHide, fctShow } = this.props;
const elements = ["1", "2", "3", "4"];
const items = [];
for (const [index, value] of elements.entries()) {
items.push(
<button
key={index}
onClick={() => {
fctShow(index);
}}
>
{value}
</button>
);
}
// if (isActive) {
return (
<div>
<table>
<tbody>
<tr>
<td> {items} </td>
</tr>
</tbody>
</table>
</div>
);
// } else {
// return null;
// }
}
}
class Prog1 extends React.Component {
render() {
const { isActive, selected, fctHide } = this.props;
if (isActive) {
return (
<div className="contProg1">
<button onClick={fctHide}>Close</button>
<h1>Program 1</h1>
<h2>Test1</h2>
<h2>Test2</h2>
<h2>Test3</h2>
Selected: {selected}
<ul>
<li>AAAAA</li>
<li>BBBBB</li>
<li>CCCCC</li>
</ul>
</div>
);
} else {
return null;
}
}
}
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { isActive: true, selected: null };
}
fctShow = selected => {
this.setState({ isActive: true, selected });
};
fctHide = () => {
this.setState({ isActive: false });
};
render() {
const { isActive, selected } = this.state;
return (
<>
<Dash
isActive={isActive}
fctHide={this.fctHide}
fctShow={this.fctShow}
/>
<Prog1 isActive={isActive} selected={selected} fctHide={this.fctHide} />
</>
);
}
}
好的!我最终使用了建议的 react-router。但是我使用了 Hooks 版本(带有 ...)
因此,小仪表板分为 X 个部分:
- HTML只有最小值和根。
<div id="root"></div>
- CSS(无话可说)
- 特定文件夹“Apps”中的子应用程序
import React from "react";
import { A } from "hookrouter";
class Prog1 extends React.Component {
render() {
return (
<div class="contProg1">
<button class="close">
{" "}
<A href="/">Close</A>
</button>
<h1>Program 1</h1>
<h2>Test1</h2>
<h2>Test2</h2>
<h2>Test3</h2>
<ul>
<li>AAAAA</li>
<li>BBBBB</li>
<li>CCCCC</li>
</ul>
</div>
);
}
}
export default Prog1;
- 在应用程序和主 Dash 之间切换的路由器页面。
import React from "react";
import Prog1 from "./Apps/Prog1";
import Prog2 from "./Apps/Prog2";
import Prog3 from "./Apps/Prog3";
import Prog4 from "./Apps/Prog4";
import Dash from "./App";
const routes = {
"/": () => <Dash />,
"/Prog1": () => <Prog1 />,
"/Prog2": () => <Prog2 />,
"/Prog3": () => <Prog3 />,
"/Prog4": () => <Prog4 />
};
export default routes;
- 主页,仪表板 (App.js)。
import React from "react";
import { A } from "hookrouter";
const elements = ["1", "2", "3", "4"];
function Dash() {
const items = [];
for (const [index, value] of elements.entries()) {
items.push(
<A href={"/Prog" + (index + 1)}>
<button key={index}>{value}</button>
</A>
);
}
return (
<div className="Dash">
<table>
<tr>
<td> {items} </td>
</tr>
</table>
</div>
);
}
export default Dash;
- 最后,索引页:
import React from "react";
import { render } from "react-dom";
import "./styles.css";
import { useRoutes } from "hookrouter";
import routes from "./router";
import NoPageFound from "./Apps/404";
function App() {
const routeResult = useRoutes(routes);
return <div className="Dash">{routeResult || <NoPageFound />}</div>;
}
render(<App />, document.getElementById("root"));
效果很好。我只需要添加 MemoryRouter 之类的东西来隐藏 URL 并为移动版本做准备。
当我将这部分插入 Django 项目时,我有点害怕。
或者,也许我应该把它分开? (你不用回答,我想我就关了)。
谢谢:)
我是 React 的初学者,我想制作一个带有仪表板的网络应用程序,如 Windows 磁贴。 我很容易生成它们。但我希望当我点击其中一个时,隐藏 Dash 菜单并显示子应用程序“Prog1”。当然,扭转它。当我单击关闭按钮时,它会关闭子应用程序并 returns 到 Dash 菜单(暗示它隐藏 Prog1 以显示 Dash)。
我可以用这样的函数隐藏 Dash 菜单:
fctHide = () => {
this.setState({ isActive: false });
}
但是我怎样才能显示另一个可能具有 fctShow 之类功能的子应用程序?
我们是被迫将函数放在 class 中还是只是制作一个通用的 display/hide 函数? 有没有更简单和更新的方法来做到这一点(例如使用钩子)。
我的应用在 Codepen 上:codepen 我可以按需在这里给你看。
我很惊讶地看到很多问题或教程显示和隐藏按钮中的元素而不是在 class/HTML/template 等之间切换(我猜像 React Native 路由器)。
谢谢!
除非您要将旧应用程序转换为 React,即不是从头开始编写纯 React 应用程序,否则不要多次使用 ReactDOM.render。由于您想在组件之间共享活动状态,因此它应该存在于它们的 closest common ancestor.
中我不确定您的仪表板应该如何工作,但这里有一个 demo. Here, APP is such closest ancestor. You don't need react-router if you are not using URL routes or the History API。
import React from "react";
import "./styles.css";
class Dash extends React.Component {
render() {
const { isActive, fctHide, fctShow } = this.props;
const elements = ["1", "2", "3", "4"];
const items = [];
for (const [index, value] of elements.entries()) {
items.push(
<button
key={index}
onClick={() => {
fctShow(index);
}}
>
{value}
</button>
);
}
// if (isActive) {
return (
<div>
<table>
<tbody>
<tr>
<td> {items} </td>
</tr>
</tbody>
</table>
</div>
);
// } else {
// return null;
// }
}
}
class Prog1 extends React.Component {
render() {
const { isActive, selected, fctHide } = this.props;
if (isActive) {
return (
<div className="contProg1">
<button onClick={fctHide}>Close</button>
<h1>Program 1</h1>
<h2>Test1</h2>
<h2>Test2</h2>
<h2>Test3</h2>
Selected: {selected}
<ul>
<li>AAAAA</li>
<li>BBBBB</li>
<li>CCCCC</li>
</ul>
</div>
);
} else {
return null;
}
}
}
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { isActive: true, selected: null };
}
fctShow = selected => {
this.setState({ isActive: true, selected });
};
fctHide = () => {
this.setState({ isActive: false });
};
render() {
const { isActive, selected } = this.state;
return (
<>
<Dash
isActive={isActive}
fctHide={this.fctHide}
fctShow={this.fctShow}
/>
<Prog1 isActive={isActive} selected={selected} fctHide={this.fctHide} />
</>
);
}
}
好的!我最终使用了建议的 react-router。但是我使用了 Hooks 版本(带有 ...)
因此,小仪表板分为 X 个部分:
- HTML只有最小值和根。
<div id="root"></div>
- CSS(无话可说)
- 特定文件夹“Apps”中的子应用程序
import React from "react";
import { A } from "hookrouter";
class Prog1 extends React.Component {
render() {
return (
<div class="contProg1">
<button class="close">
{" "}
<A href="/">Close</A>
</button>
<h1>Program 1</h1>
<h2>Test1</h2>
<h2>Test2</h2>
<h2>Test3</h2>
<ul>
<li>AAAAA</li>
<li>BBBBB</li>
<li>CCCCC</li>
</ul>
</div>
);
}
}
export default Prog1;
- 在应用程序和主 Dash 之间切换的路由器页面。
import React from "react";
import Prog1 from "./Apps/Prog1";
import Prog2 from "./Apps/Prog2";
import Prog3 from "./Apps/Prog3";
import Prog4 from "./Apps/Prog4";
import Dash from "./App";
const routes = {
"/": () => <Dash />,
"/Prog1": () => <Prog1 />,
"/Prog2": () => <Prog2 />,
"/Prog3": () => <Prog3 />,
"/Prog4": () => <Prog4 />
};
export default routes;
- 主页,仪表板 (App.js)。
import React from "react";
import { A } from "hookrouter";
const elements = ["1", "2", "3", "4"];
function Dash() {
const items = [];
for (const [index, value] of elements.entries()) {
items.push(
<A href={"/Prog" + (index + 1)}>
<button key={index}>{value}</button>
</A>
);
}
return (
<div className="Dash">
<table>
<tr>
<td> {items} </td>
</tr>
</table>
</div>
);
}
export default Dash;
- 最后,索引页:
import React from "react";
import { render } from "react-dom";
import "./styles.css";
import { useRoutes } from "hookrouter";
import routes from "./router";
import NoPageFound from "./Apps/404";
function App() {
const routeResult = useRoutes(routes);
return <div className="Dash">{routeResult || <NoPageFound />}</div>;
}
render(<App />, document.getElementById("root"));
效果很好。我只需要添加 MemoryRouter 之类的东西来隐藏 URL 并为移动版本做准备。 当我将这部分插入 Django 项目时,我有点害怕。 或者,也许我应该把它分开? (你不用回答,我想我就关了)。
谢谢:)