ReactJS 使用有状态和无状态组件的正确方法?
ReactJS correct way to use of stateful and stateless components?
我开始学习ReactJS,对无状态组件和有状态组件有疑问。通常我遵循组件和容器的分离,如下所示。有状态函数在组件文件夹下,其他逻辑操作在容器文件夹下。
folder structure
让我们想想 material 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()
方法改变打开状态,这意味着它是有状态的组件。但是没有其他变化(省略年龄设置)。它似乎是可重用的组件,但包含状态,操作非常简单,如打开和关闭。我应该放在哪个文件夹?容器还是组件?
其实除了文件夹选择,我还可以给open状态作为回调函数和open状态作为props。但我认为在每个容器中这样做可能有点矫枉过正,并且因为只打开下拉列表而重新渲染父容器(React.memo 可以处理它但在任何地方都使用它似乎很奇怪)。
1-简单操作的正确使用方法是什么?将功能作为道具提供或在组件中使用状态?
2- 如果我使用 props 渲染会导致性能问题,因为整个其他组件都会渲染吗?
提前致谢。
容器组件:
这些组件执行繁重的逻辑,主要是基于路由或(更确切地说是繁重的)逻辑。
功能组件:
这些功能是可用的小(或可能很大)但主要目的是它们在几个容器组件中可用,事件可能在其他功能组件中,功能组件的目的是信誉,它们持有一些状态(就像在你的情况下保持一个简单的挂钩状态来跟踪切换)我可以说完全没问题
大多数情况下,您会发现自己在连接 Redux 的路由级别使用容器组件(我也应该注意,这些天不鼓励这样做)和嵌套在子组件内的许多其他功能组件。
所以为了回答你的问题,我可以这样说:
- 对于简单的操作,您不要必须在父级中保持状态
组件并将其传递给您的功能组件,
这导致你将道具传递给你的子组件
并使项目维护变得如此棘手并导致错误代码,
在子组件中保持简单状态是完全可以的
- 我觉得没那么多,如果你只传递简单的道具...
更好地使用功能组件中的新功能,react 挂钩和上下文,而不是使用基于 class 的组件或询问有状态或无状态组件
我开始学习ReactJS,对无状态组件和有状态组件有疑问。通常我遵循组件和容器的分离,如下所示。有状态函数在组件文件夹下,其他逻辑操作在容器文件夹下。 folder structure
让我们想想 material 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()
方法改变打开状态,这意味着它是有状态的组件。但是没有其他变化(省略年龄设置)。它似乎是可重用的组件,但包含状态,操作非常简单,如打开和关闭。我应该放在哪个文件夹?容器还是组件?
其实除了文件夹选择,我还可以给open状态作为回调函数和open状态作为props。但我认为在每个容器中这样做可能有点矫枉过正,并且因为只打开下拉列表而重新渲染父容器(React.memo 可以处理它但在任何地方都使用它似乎很奇怪)。
1-简单操作的正确使用方法是什么?将功能作为道具提供或在组件中使用状态?
2- 如果我使用 props 渲染会导致性能问题,因为整个其他组件都会渲染吗?
提前致谢。
容器组件:
这些组件执行繁重的逻辑,主要是基于路由或(更确切地说是繁重的)逻辑。
功能组件:
这些功能是可用的小(或可能很大)但主要目的是它们在几个容器组件中可用,事件可能在其他功能组件中,功能组件的目的是信誉,它们持有一些状态(就像在你的情况下保持一个简单的挂钩状态来跟踪切换)我可以说完全没问题
大多数情况下,您会发现自己在连接 Redux 的路由级别使用容器组件(我也应该注意,这些天不鼓励这样做)和嵌套在子组件内的许多其他功能组件。
所以为了回答你的问题,我可以这样说:
- 对于简单的操作,您不要必须在父级中保持状态
组件并将其传递给您的功能组件, 这导致你将道具传递给你的子组件 并使项目维护变得如此棘手并导致错误代码, 在子组件中保持简单状态是完全可以的 - 我觉得没那么多,如果你只传递简单的道具...
更好地使用功能组件中的新功能,react 挂钩和上下文,而不是使用基于 class 的组件或询问有状态或无状态组件