reactjs - ReactJS 正确使用有状态和无状态组件的方法?
问题描述
我已经开始学习 ReactJS 并且有一个关于无状态和有状态组件的问题。一般来说,我遵循组件和容器的分离,如下所示。有状态的函数在组件文件夹和容器文件夹下的其他逻辑操作。 文件夹结构
让我们想想材质 UI 下拉列表。
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
const useStyles = makeStyles(theme => ({
button: {
display: 'block',
marginTop: theme.spacing(2),
},
formControl: {
margin: theme.spacing(1),
minWidth: 120,
},
}));
export default function ControlledOpenSelect() {
const classes = useStyles();
const [age, setAge] = React.useState('');
const [open, setOpen] = React.useState(false);
const handleChange = event => {
setAge(event.target.value);
};
const handleClose = () => {
setOpen(false);
};
const handleOpen = () => {
setOpen(true);
};
return (
<div>
<FormControl className={classes.formControl}>
<InputLabel id="demo-controlled-open-select-label">Age</InputLabel>
<Select
labelId="demo-controlled-open-select-label"
id="demo-controlled-open-select"
open={open}
onClose={handleClose}
onOpen={handleOpen}
value={age}
onChange={handleChange}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</div>
);
}
为了打开和关闭下拉列表handleClose()
和handleOpen()
方法改变打开状态,这意味着它是有状态的组件。但是没有其他变化(省略年龄设置)。它似乎是可重用的组件,但包含具有非常简单操作的状态,例如打开和关闭。我应该放在哪个文件夹?容器还是组件?
实际上除了文件夹选择之外,我可以将打开状态作为回调函数,将打开状态作为道具。但我认为在每个容器中执行此操作可能有点过分,并且由于仅打开下拉列表而重新渲染父容器(React.memo 可以处理它,但在任何地方都使用它似乎很奇怪)。
1-使用简单操作的正确方法是什么?将功能作为道具或在组件中使用状态?
2-如果我使用道具,渲染是否会导致性能问题,因为整个其他组件都会渲染?
提前致谢。
解决方案
容器组件:
这些是执行重逻辑的组件,主要是基于路由或(更好地说是重)基于逻辑的组件。
功能组件:
这些功能可以使用很小(或可能很大),但主要目的是它们可以在多个容器组件中使用,并且事件可能在其他功能组件中,功能组件的目的是信誉,它们保持某种状态(比如保持简单挂钩状态以跟踪您的情况下的切换)我可以说这完全没问题
大多数时候,您会发现自己在连接 Redux 的路由级别使用容器组件(我也应该注意,这些天不鼓励使用)以及嵌套在子组件中的许多其他功能组件。
所以为了回答你的问题,我可以这样说:
- 对于简单的操作,您不必在父
组件中保持状态并将其传递给您的功能组件,这会导致您将大量道具传递给您的子组件,并使项目维护变得如此棘手并导致代码错误,这完全是可以在子组件中保持简单状态 - 我想没那么多,如果你只通过简单的道具......
推荐阅读
- spring - Spring 类级别验证和 Thymeleaf
- javascript - push() 后数组为空
- r - r rvest 使用多个网站抓取多个 url,并且在某些节点中缺少值
- vhdl - 我在波形中的一个 CLK 周期内收到错误的信号
- android - 在 Kotlin 中以编程方式更改语言环境
- c# - 在运行时创建多个文本框并从数据库中分配值文本框..我想显示数据库中的所有数据
- python - 提取具有多个 URL 的字符串
- c++ - 返回递归和基本流程
- jwplayer - 将设置传递给 amp-jwplayer 插件
- firebase - 错误解析触发器:找不到模块“@custom-path”