尝试通过调用 API 来设置功能模块的初始状态。我阅读了有关 useState 以设置初始值和 useEffect 的信息,它在呈现页面时运行,因此我的表单页面从 api 获取默认值,并且用户会看到预先填写的表单。
现在我的问题是,当我尝试在 return(( 中的表单中使用 api 值时,我没有预先填充其中的值。如果我在useState({"sor_name": "ani"}(中对值进行硬编码,我能够获取表单中的值。为了便于阅读,我缩短了代码。 这是我的代码:
const UpdateSOR = (props) => {
const [SOR, setSOR] = useState([]); // Initialized SOR
async function getSOR() {
const res = await QueryService.getSOR(2).then(
res => {
if (res.status === 200) {
setSOR(res.data.data.dataItems[0]); // I get the values in the form {"data":{"dataItems":[{"SOR_NAME":"ani"}]}}
}
}
).catch(error => {
console.log(error);
})
}
useEffect(() => {
getSOR(); // called SOR
}, []);
return (
<form className={`${classes.form} ${classes.body}`} noValidate autoComplete="off">
<Row>
<Col lg="2" onChange = {(event) => setSelectedSorName(event.target.value)}>
<CommonInput
id="sor_name"
label="SOR Name"
defaultValue={SOR.SOR_NAME} // i dont get the value here on initial load.
disabled={false}
multiline={false}
rows="1" />
</Col>
</Row>
</form>
)
注意:这是我的功能模块树结构: app-->appBar(component(-->SOR(module(--> updateSOR(module(
如果用户像这样直接来更新 OR (localhost:3000/edit/updateSOR/2(,我想运行 api 并获取值并填写表单并直接呈现给用户。我知道我可以直接从上一页(即 SOR(将 api 值推送到 props,但这样做仅在用户从 SOR 进入页面时才有效,但如果用户直接输入带有 id 的页面名称,我需要填充该 updateSOR 页面。
这是我在 QueryService 中编写的函数,它获取数据,我在 useEffect 钩子中调用此 updateSOR 组件以获取数据:
function getSOR(id) {
if(id) {
return axios.get(`${Constants.API_URL}/SOR?id=${id}`);
} else {
return axios.get(`${Constants.API_URL}/SOR`);
}
}
这是我的 CommonInput 函数。
export default function CommonInput(props) {
const classes = useStyles();
const { id , label, defaultValue, disabled, multiline, rows } = props;
return (
<FormControl className={classes.formControl}>
<InputLabel id={id}>{label}</InputLabel>
<Input
defaultValue={defaultValue}
id={id}
disabled={disabled}
multiline={multiline}
rows={rows}
/>
</FormControl>
)
}
为了理解问题,你需要首先了解useEffect
是如何工作的。根据 React Hooks API 参考:
传递给 useEffect 的函数将在渲染提交到屏幕后运行。
useEffect
中为获取数据而进行的异步调用在组件首次呈现后执行。因此,组件以初始状态呈现,该状态为空。网络调用完成后,将调用setSOR
,从而触发具有新状态的重新渲染。
一种解决方案是在退货前为未解决的状态提供退货条件。如果您不想渲染任何内容或某种加载指示器,这可以简单地return false
。
示例:(我省略了一些代码来突出这个概念(
function UpdateSOR() {
const [SOR, setSOR] = useState(); // default to undefined state.
useEffect(() => {
QueryService.getSOR(2).then(res => {
if (res.status === 200) {
setSOR(res.data.data.dataItems[0]);
}
});
}, []);
if (!SOR) return false; // Render nothing, <p>Loading...</p>, etc.
return <p>{SOR.SOR_NAME}</p>
}