渲染多次?

时间:2020-09-10 14:38:21

标签: javascript reactjs redux

我有一个表单组件,输入字段的引用通过引用链接到useForm reducer。设置输入字段引用后,我必须设置初始表单状态吗?我做了如下。但这是三次渲染。如何解决此渲染问题?

import React, { useState } from 'react';

const useForm = () => {

    const [ formState, setFormState ] = useState({});
    const refs = useRef({});

    const register = useCallback(( fieldArgs ) => ref => {
        if(fieldArgs) {
            const { name, validations, initialValue } = fieldArgs;
    
            refs.current[name] = ref;
        }
        console.log('Register rendered');
    }, []);

    useEffect(() => {
        console.log('Effect Rendered');
        const refsKeys = Object.keys(refs.current);
        refsKeys.forEach(refKey => {
            if(!formState[refKey]) {
                setFormState(prevState => {
                    return {
                        ...prevState,
                        [refKey]: {
                            value: '',
                            touched: false,
                            untouched: true,
                            pristine: true,
                            dirty: false
                        }
                    }
                });
            }
        });
    }, [ refs ]);

    return [ register ];
}

export { useForm };

以及以下应用程序组件

const App = () => {

    const [ register ] = useFormsio();

    return(
        <form>

            <input
                type = 'email'
                placeholder = 'Enter your email'
                name = 'userEmail'
                ref = { register({ name: 'userEmail' }) } />

            <button
                type = 'submit'>
                    Submit
            </button>

        </form>
    )
}

enter image description here

如何解决此多重渲染问题?

1 个答案:

答案 0 :(得分:0)

我认为上面代码中的问题是,只要引用更改,您就需要遍历表单中的所有字段并设置状态。 为什么不通过注册方法设置状态?

const register = useCallback(( fieldArgs ) => ref => {
        if(fieldArgs) {
            const { name, validations, initialValue } = fieldArgs;
            if(!refs.current[name] ) {
                refs.current[name] = ref;
                setFormState(prevState => {
                    return {
                        ...prevState,
                        [refKey]: {
                            value: '',
                            touched: false,
                            untouched: true,
                            pristine: true,
                            dirty: false
                        }
                    }
                });
            }
        }
        console.log('Register rendered');
    }, []);