Skip to content

Instantly share code, notes, and snippets.

@noctifer20
Created April 13, 2021 11:45
Show Gist options
  • Save noctifer20/dd6d6a3d5004376c74beea9ce20de12a to your computer and use it in GitHub Desktop.
Save noctifer20/dd6d6a3d5004376c74beea9ce20de12a to your computer and use it in GitHub Desktop.
React Native - auto focus next input using context
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;
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