0

I made the following screen where each label + input combo is inside a child component. When I click save (salvar) I want to inspect each component's ref to see if it has a "isInvalid" variable set to true and then paint the border red and show an error message. That means the field is required, etc.

enter image description here

I've tried creating a ref in the parent component like this:

export default function DiaryExam({ navigation }) {

let examNameRef =  useRef();

return (
    <Page type="static" title={'Avaliação'} subtitle={'Editar'}>
            <FormInput ref={examNameRef} inputType="text" title={"Nome da avaliação"} value={name} setValue={setName} required />
            //I'll add the other refs below later
            <FormInput inputType="text" title={"Código"} value={code} setValue={setCode} maxLength={8} required/>
            <FormInput inputType="number" title={"Nota máxima"} value={maxGrade} setValue={setMaxGrade} />
            <FormInput inputType="number" title={"Peso"} value={weight} setValue={setWeight} required />
            <FormInput inputType="date" title={"Data de Início"} value={startDate} setValue={setStartDate} />
            <FormInput inputType="date" title={"Data de Fim"} value={endDate} setValue={setEndDate} />
            <FormInput inputType="switch" title={"Ignorar na Fórmula"} value={ignoreFormula} setValue={setIgnoreFormula} />
            <Button style={[styles.button, {}]} textStyle={styles.buttonText} title={'Salvar'} onPress={() => saveExam()} requestFeedback />
    </Page>
);

In the child component I have something like this ( among other things) :

export default function FormInput ({ inputType, title, value, setValue, required, maxLength, ref }) {

return (
    <View>
        {(inputType === 'text' || inputType === 'number') && (
            <View>
                <Text ref={ref} style={[styles.fieldValue, { borderColor: requiredValidationError ? 'red' : 'grey' }]}>{value}</Text>
                <Text style={[{ alignSelf: 'flex-end', backgroundColor: 'white', color: requiredValidationError ? 'red' : 'grey' }]}>{requiredValidationError? 'Campo obrigatório' : ''}</Text>
            </View>
        )}
        </View>
)

I need to see if the 'value' variable is length === 0 if the 'required' prop is true and then set setRequiredValidationError(true) so it'll change the layout accordingly.

But all I get is the following error in the console:

[Tue Mar 09 2021 17:21:48.858]  ERROR    Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

I have googled react native forwardRef, but all the examples and documentations are for traditional React or they use class components and nothing I've tried works. How would I do that?

1 Answer 1

3

As per the warning, you need to use React.forwardRef. You can do it like this:

const FormInput = React.forwardRef(({ 
    inputType, 
    title, 
    value,
    setValue, 
    required, 
    maxLength
}, ref) => {
    return (
        {(inputType === 'text' || inputType === 'number') && (
            <View>
                <Text ref={ref} style={[styles.fieldValue, { borderColor: requiredValidationError ? 'red' : 'grey' }]}>{value}</Text>
                <Text style={[{ alignSelf: 'flex-end', backgroundColor: 'white', color: requiredValidationError ? 'red' : 'grey' }]}>{requiredValidationError? 'Campo obrigatório' : ''}</Text>
            </View>
        )}
    )
}

More info in the React doc, which uses functional component.

Sign up to request clarification or add additional context in comments.

2 Comments

That worked, ty. I had alread tried this way but I think I was trying to do export default function FormInput = React.forwardRef instead of const FormInput = React.forwardRef

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.