React Hook "useEffect" 在据称简单的获取-显示-检索输入组件中被有条件地调用



请帮忙,我在兜圈子(新的React)。
我得到'React Hook "useState"如果我把它改成下面的代码,我就会得到'React Hook "useEffect">

这个想法是

  1. 通过useQuery和通过props传入的db记录id检索数据。
  2. 如果该数据为空,例如查询使用id=0(如插入而不是更新记录),则deviceObject为空记录,否则为检索数据。
  3. 设置'deviceObject'进入状态

。顺序很重要,但是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();

在condition之后调用钩子。它使得你调用的钩子在渲染之间不会以相同的顺序出现,因为"React依赖于钩子被调用的顺序"。

你可以在本文档中找到有用的信息,也可以找到解决问题的方法。

https://reactjs.org/docs/hooks-rules.html解释更新:

  • 你当然不应该在句柄中放置钩子。
  • 如果你仍然想保留原始代码,你可以提取block后的条件到其他组件,像这样
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 (...);
}

最新更新