通过API调用设置表单的初始值

时间:2020-07-17 18:09:20

标签: reactjs react-hooks formik

在我的React游戏中,我使用一个称为Formik的React库作为表单。

在其中,您可以为表单设置初始值,如下所示:

<Formik
    initialValues={{
        characterClasses: ["1", "3", "9"],
        race: "Elf",
        name: "Derolt",
        age: "84",
        
        ..etc
        

但是现在,我处于一种想从API调用中加载初始值的状态。

所以我创建了这个:

const fetchGameCharData = async (gameId) => {
    const game = await axios("api/games/" + gameId);
    // return the result
    return game;
};

我的问题是,我不知道如何使用上述提取方法来实际填充Formik使用的initialValues部分。

有人做过吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

如果您使用的是类组件:

componentDidMount() {
    this.fetchGame();
}

async fetchGame() {
    const game = await fetchGameCharData(GAME_ID);
    this.setState({ game });
}
...
// in render method
const { game } = this.state;
...
<Formik
    initialValues={game}
...

如果您使用的是功能组件:

const { game, setGame } = useState();

useEffect(async () => {
    const game = await fetchGameCharData(GAME_ID);
    setGame(game);
}, []);

...
// in return
<Formik
    initialValues={{
        characterClasses: ["1", "3", "9"],
        race: "Elf",
        name: "Derolt",
        age: "84",
        ...
    }}
    values={game}
...

只需确保仅在Formik可用时才渲染game。 否则将是错误的,因为initialValues要求对象具有表单所需的所有属性。

答案 1 :(得分:1)

使用conditional-rendering方法。

仅在获得API调用的响应后才加载表单。显示loading...或自定义spinner,直到获得API响应为止。

通过这种方法,您的表单可以直接加载initial values,而不会在第一次加载时闪烁任何值,并且由于API响应而在瞬间出现值。

编辑

// In your state add two values like
initialValues: [],
isValueLoded: false

...

// Make your API call in `componentDidMount`
componentDidMount() {
    // Call your API
    fetchGameCharData(....).then(res => {
        this.setState({ isValueLoded: true, initialValues: res.values});
    }).catch(err => ....);
}

....

// In your render method
render() {

    return !this.state.isValueLoded ?
       (<div>Loading...</div>) : (
        <Formki
          values={this.state.initialValues}
         ....
         />
    );
}