기본 반응, 자동 초점 다음 TextInput

12798 단어 reactnative

문제



기본적으로 ReactNative는 제출 시 다음에 초점을 맞추는 것을 지원하지 않습니다<TextInput/>.

마구 자르기



Inspired by this StackOverflow answer



마운트된 FormContext에서 Context을 생성하는 <TextInput/>라는 이름의 LinkedList을 사용합니다.<TextInput/> 를 구성 요소에 래핑하면 <TextInput/> 에서 다음FormContext 을 찾아 초점을 맞춥니다.

다음은 FormContextFormContextProvider의 모양입니다.

// form.context.js

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;


다음은 <TextInput/> 래퍼 구현입니다.

// wrapped-input.js

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);
      }}
    />
  )
}

좋은 웹페이지 즐겨찾기