Formik&Mobx从API设置初始值

时间:2020-05-09 21:14:59

标签: reactjs mobx formik

允许我以说我是新来的人作为我的开头,我看过其他帖子,但仍然无法解决此问题。

我的问题如下,我正在尝试创建一个表格,该表格允许用户输入自己锻炼的一部分,每次练习的次数,设置和所用的体重。但是,如果用户尝试输入任何内容,则其作用类似于只读字段。我怀疑我设置初始值的方式有问题。在我的WorkoutStore.ts中,我定义了一个名为ExercisesForForm的计算值,如下所示:

class MyInt(int):

    def __new__(cls, *args, **kwargs):
        value = super().__new__(cls, *args, **kwargs)
        argstr = ', '.join([str(arg) for arg in args]) # Only for prototype test
        print('MyInt({}); Returned {}'.format(argstr, value)) # Only for prototype test
        if value < 0 or value > 100:
            raise ValueError('  ERROR!! Out of range! Must be 0-100, was {}'.format(value))
        return value


if __name__ == '__main__':
    myint = MyInt('1111', 2)  # Test conversion from binary string, base 2
    print('myint = {} (type: {})\n'.format(myint, type(myint)))

    for index, arg in enumerate([-99, -0.01, 0, 0.01, 0.5, 0.99, 1.5, 100, 100.1, '101']):
        try:
            a = MyInt(arg)
        except ValueError as ex:
            print(ex)
            a = None
        finally:
            print('  a : {} = {}'.format(type(a), a))

当我控制台日志时,我可以清楚地看到它已正确设置。但是,如果我尝试访问它或其他任何内容,都会不断抱怨它未定义。因此,主要的问题实际上是:定义从API端点接收的初始值的正确方法是什么?如果这只是一种专门针对一个实体的形式(例如,像一个练习一样),那么会容易得多,因为那样的话,它将简单地将数据1:1映射到表单中的元素

我正在尝试如下定义表单:

 @computed get exercisesForForm() {
        const data = this.exercises.map((e) => ({
            name: e.name,
            id: e.id,
            sets: e.sets,
            reps: e.reps,
            weight: e.weight

        }));

        return data;
    }

对此的后续问题是,如何正确定义表单的名称部分?在MVC.NET(这是我最熟悉的Web明智方法)中,我只需定义一个数组并使用const rootStore = useContext(RootStoreContext); const {getExercises, exercises, exercisesForForm} = rootStore.workoutStore; useEffect(() => { if(match.params.workoutId) { getExercises(match.params.workoutId); } }, [getExercises, match.params.workoutId]) <Formik key={uuid()} onSubmit={handleFormSubmit} initialValues={exercisesForForm} enableReinitialize={true}> {({ handleSubmit, handleChange, values }) => ( <Form onSubmit={handleSubmit}> {exercises.map((exercise, index) => ( <Fragment key={exercise.id}> <Header>{exercise.name}</Header> <Form.Row> <Form.Group as={Col}> <Form.Label>Sets</Form.Label> <Form.Control key={uuid()} type="number" name='sets' value={0} onChange={handleChange}/> </Form.Group> </Form.Row> <Form.Row> <Form.Group as={Col}> <Form.Label>Reps</Form.Label> <Form.Control key={uuid()} type="number" name='reps' onChange={handleChange}/> </Form.Group> </Form.Row> <Form.Row> <Form.Group as={Col}> <Form.Label>Weight</Form.Label> <Form.Control key={uuid()} type="number" name='weight' onChange={handleChange}/> </Form.Group> </Form.Row> </Fragment> ) )} <Form.Row> <Form.Group as={Col} controlId='04'> <Button content="Submit" floated='right' type="submit"/> </Form.Group> </Form.Row> </Form> )}</Formik>

之类的方法动态创建输入

1 个答案:

答案 0 :(得分:0)

经过大量的搜索,实验和重新阅读文档之后,我得以弄清楚。我将代码更改如下:

<Formik key={uuid()} onSubmit={handleFormSubmit}  enableReinitialize={true} initialValues={exercisesForForm}
                        render={({values, handleChange, handleSubmit}) => (
                            <Form onSubmit={handleSubmit}>
                                        {values.map((e, index) => (
                                            <Fragment key={index}>
                                                <Header>{e.name}</Header>
                                                <Form.Row>
                                                    <Form.Group as={Col}>
                                                        <Form.Label>Sets</Form.Label>
                                                        <Form.Control key={`${index}_sets`} type='number' name={`[${index}].sets`} value={(e.sets)} onChange={handleChange} />
                                                    </Form.Group>
                                                </Form.Row>
                                                <Form.Row>
                                                    <Form.Group as={Col}>
                                                        <Form.Label>Reps</Form.Label>
                                                        <Form.Control key={`${index}_reps`} type='number' name={`[${index}].reps`} value={(e.reps)} onChange={handleChange} />
                                                    </Form.Group>
                                                </Form.Row>
                                                <Form.Row>
                                                    <Form.Group as={Col}>
                                                        <Form.Label>Weight</Form.Label>
                                                        <Form.Control key={`${index}_weight`} type='number' name={`[${index}].weight`} value={(e.weight)} onChange={handleChange} />
                                                    </Form.Group>
                                                </Form.Row>
                                            </Fragment>
                                        )

                                    )}
                                )}
                                <Form.Row>
                                    <Form.Group as={Col} controlId='04'>
                                        <Button content="Submit" floated='right' type="submit"/>
                                    </Form.Group>
                                </Form.Row>
                            </Form>
                        )}
                    />  

需要注意的事情:我正在使用values属性来访问初始值;我也使用索引来设置字段的名称。我认为那是将其联系在一起的缺失环节。