Reputation: 493
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.
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?
Upvotes: 0
Views: 11636
Reputation: 1443
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.
Upvotes: 3