Created
April 13, 2021 11:45
-
-
Save noctifer20/dd6d6a3d5004376c74beea9ce20de12a to your computer and use it in GitHub Desktop.
React Native - auto focus next input using context
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const FormContext = createContext({}); | |
let inputsLL = null; | |
let lastInput = null; | |
const FormContextProvider = ({ children }) => { | |
useEffect(() => { | |
inputsLL = null; | |
lastInput = null; | |
}, []); | |
return ( | |
<FormContext.Provider | |
value={{ | |
actions: { | |
addInput(name, ref) { | |
ref.name = name; | |
if (!inputsLL) { | |
inputsLL = ref; | |
lastInput = ref; | |
} else if (lastInput) { | |
lastInput.next = ref; | |
lastInput = ref; | |
} | |
}, | |
removeInput(name) { | |
if (inputsLL) { | |
let node = inputsLL; | |
let parent = null; | |
do { | |
if (node.name === name) { | |
if (parent && node.next) { | |
parent.next = node.next; | |
} else if (parent && !node.next) { | |
parent.next = null; | |
} else if (!parent && node.next) { | |
inputsLL = node.next; | |
} else if (!parent && !node.next) { | |
inputsLL = null; | |
} | |
break; | |
} | |
parent = node; | |
node = node.next; | |
} while (node); | |
} | |
}, | |
focusNext(name) { | |
if (inputsLL) { | |
let node = inputsLL; | |
do { | |
if (node.name === name) { | |
if (node.next) { | |
node.next.focus(); | |
} else node.blur(); | |
} | |
node = node.next; | |
} while (node); | |
} | |
}, | |
}, | |
inputs: inputsLL, | |
}} | |
> | |
{children} | |
</FormContext.Provider> | |
); | |
}; | |
export default FormContextProvider; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default function WrappedInput(props) { | |
let reference = useRef(null); | |
const { actions } = useContext(FormContext); | |
useEffect(() => { | |
//label must be unique | |
actions.addInput(props.label, reference); | |
return () => { | |
actions.removeInput(props.label); | |
}; | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, [reference]); | |
return ( | |
<TextInput | |
ref={(r) => (reference = r)} | |
blurOnSubmit={false} | |
onSubmitEditing={() => { | |
actions.focusNext(props.label); | |
}} | |
/> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment