reactjs - React Hook "useEffect" 被有条件地调用,在所谓的简单的 get-display-retrieve 输入组件中
问题描述
请帮忙,我在绕圈子(React 新手)。
我要么得到“有条件地调用 React Hook “useState”,如果我将其更改为下面的代码,
我得到“有条件地调用 React Hook “useEffect”。
这个想法是
- 通过 useQuery 检索数据,并通过 props 输入数据库记录 ID。
- 如果该数据为空,例如查询使用 id=0(如插入而不是更新记录),则 deviceObject 为空记录,否则为检索到的数据。
- 将“deviceObject”设置为状态。
ie 顺序很重要,但是 setRow 应该只调用一次,而不是多次,这会导致渲染过多导致反应崩溃。
export default function DeviceModal(props) {
const dataRowId = props.dataRowId;
const classes = useStyles();
const [row, setRow] = useState('')
const device = useQuery(getDevice_query, {variables: {id: dataRowId}});
if (device.loading) return <DataLoader/>;
if (device.error) return <p style={{color: 'white'}}>{("GraphQL Error " + device.error)})</p>;
// Create an empty recordObject to be populated and sent back for insert to db.
const emptyDevice = {
id : 0,
deviceId : 0,
deviceClass :{name : '',},
serialNumber: 0,
}
const deviceObject = device.data.getDevice !== null ? device.data.getDevice : emptyDevice;
useEffect(()=>{
setRow(deviceObject)
},[])
const handleSave = (value) => {
};
const HandleChange = e => {
useEffect(()=>{
setRow({...row, [e.target.name]: e.target.value })
},[])
};
return (
<div>
<Modal ...>
<div className={classes.paper}>
<Grid container direction="row" justify="center" alignItems="center">
<Grid item xs={4}>
<TextField
id="deviceId"
name="deviceId"
defaultValue={row.deviceId}
onChange={HandleChange}
/>
</Grid>
</Grid>
{/* 30 other textfields to capture*/}
....
</div>
</Modal>
</div>
)};
Edit as per Long Nguyen:
// Set the device object record to be either the empty record, or the records retrieved from db if those are populated (not null)
let deviceObject = {};
const Component = () => {
deviceObject = device.data.getDevice !== null ? device.data.getDevice: emptyDevice;
return <RefactorComponent />;
}
// Set the device object (empty or populated with db-retrieved rows,) into state
const RefactorComponent = () =>
{
useEffect(()=>{
setRow(deviceObject)
},[deviceObject])
// return ()
}
Component();
解决方案
你在条件之后调用钩子。它使你调用的钩子在渲染之间不会以相同的顺序出现,因为“React 依赖于调用钩子的顺序”。
您可以在本文档中找到有用的信息以及解决问题的方法。
https://reactjs.org/docs/hooks-rules.html#explanation
更新:
- 当然,你不应该把钩子放在把手上。
- 如果您仍想保留原始代码,可以像这样将条件后的块提取到其他组件
const Component = () => {
if(conditions) return <Other />
// bad, this hook order is not fixed
// it can appear or not
useEffect(() => {
...the effect after condition...
});
return (...);
}
const Component = () => {
if(conditions) return <Other />
return <RefactorComponent />
}
const RefactorComponent = () => {
// ✅ ok, the hooks order is fixed
useEffect(() => {
...the effect after condition...
});
return (...);
}
推荐阅读
- mysql - 如何在pyspark sql或Mysql中按键求和
- reflection - F# Generic Map.count 使用反射
- python - 我想从格式为 YEARWEEKNUM 的时间字段创建一个标志
- scheme - Scheme 中的语法和变量
- embedded-linux - Android - 将访问权限设置为分区
- button - Flutter:将按钮边缘与其他组件对齐
- html - 根据数值字段(列)的值,用不同的颜色阴影(每行 - 一个阴影)为 Angular 8 中的 mat-table 行着色
- python - 有没有办法擦除一列来执行 TSNE?
- react-native - 基于平面列表偏移的 React Native 动画视图位置
- javascript - 使用破坏的打字稿无状态(功能)组件警告?