setState在页面加载之前未设置api的初始值

时间:2020-05-21 19:43:39

标签: reactjs async-await react-redux react-hooks react-hook-form

尝试通过调用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)

如果用户像这样直接访问updateSOR(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>

    )

}

1 个答案:

答案 0 :(得分:1)

为了理解问题,您需要首先了解useEffect的工作方式。根据{{​​3}}:

传递给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>
}