React Native && 연산자 사용 시 변수를 문자열로 인식하는 에러
Error: Text strings must be rendered within a <Text> component.
잘 뜨던 화면이 렌더링되지 않고 에러가 났다. 내용은 문자열을 <Text> 컴포넌트로 감싸야 렌더링할 수 있다는 것이다.
{isInsufficient ? (
<Text style={{color: 'rgb(237, 58, 71)'}}>
송금가능금액이 부족해요.
</Text>
) : point == 0 ? (
<Text>송금가능금액이 없습니다.</Text>
) : null}
{point && (
<>
<Text>
송금가능금액: {parseInt(point - 500).toLocaleString('ko-KR')}원
</Text>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<View style={styles.infoIcon}>
<Text style={{color: 'rgb(156, 123, 252)', fontSize: 8}}>?</Text>
</View>
<Text style={{color: 'rgb(156, 123, 252)'}}>
수수료는 500원이 부과돼요.
</Text>
</View>
</>
)}
그런데 문제가 된 부분의 코드를 보면 당연하게도 문자열은 모두 <Text> 컴포넌트로 감쌌기 때문에 잘못된 부분이 없었다.
- [React Native] Text Strings must be rendered within a <Text> component https://eloquence-developers.tistory.com/178
위 글을 보니, {} 안에서 && 연산자를 쓸 때 문제가 생기곤 한다고 한다. && 앞에 boolean 형태의 값을 갖는 변수를 써주고 이 값이 true일 때 && 연산자 뒷부분의 컴포넌트가 렌더링되도록 조건부 렌더링을 사용했는데 이게 문제였던 것 같다. 원래 React에서 한 번도 겪은 적이 없던 문제인데 RN에서만 그러는 걸 보면 버그 같기도 하다.
{isInsufficient == true ? (
<Text style={{color: 'rgb(237, 58, 71)'}}>
송금가능금액이 부족해요.
</Text>
) : point == 0 ? (
<Text>송금가능금액이 없습니다.</Text>
) : null}
{point.length > 0 && (
<>
<Text>
송금가능금액: {parseInt(point - 500).toLocaleString('ko-KR')}원
</Text>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<View style={styles.infoIcon}>
<Text style={{color: 'rgb(156, 123, 252)', fontSize: 8}}>?</Text>
</View>
<Text style={{color: 'rgb(156, 123, 252)'}}>
수수료는 500원이 부과돼요.
</Text>
</View>
</>
)}
어쨌건 이렇게 변수만 달랑 써둔 부분을 긴 조건문(?)으로 고쳤더니 해결됐다.
수정!!! point는 숫자라서 length 메서드를 쓸 수 없다. point가 1000이라도 undefined가 나온다. 그래서 처음에는 이렇게 작동했는데 나중에 보니 해당 부분이 렌더링되지 않아서 point > 0으로 고쳤다.
useRef로 <TextInput> focus 안되는 현상
typeerror: cannot read property 'focus' of null
const ConfirmContent = () => {
const [isModal, setIsModal] = useState(false);
const senderInput = useRef();
return (
<Pressable
onPress={() => {
setIsModal(true);
senderInput.current.focus();
}}
>
<Text style={styles.blackText}>{sender}</Text>
</Pressable>
<Modal visible={isModal}>
<TextInput
value={sender}
onChangeText={text => {
setSender(text);
}}
maxLength={15}
ref={senderInput}
/>
</Modal>
</View>
);
};
아무리 코드를 들여다봐도 useRef 사용법이 잘못되지 않았는데 <Pressable>의 onPress 함수 안에서 focus()가 실행되지 않고, console.log(senderInput.current)를 찍어보면 null이라고 나온다.
그런데 <Modal> 컴포넌트 안에 다른 <Pressable> 컴포넌트를 만들고 실행시켜봤더니 인풋이 잘 포커스되었다. 그래서 코드가 잘못된게 아니라 실행된 위치의 문제라고 생각했다.
const ConfirmContent = () => {
const [isModal, setIsModal] = useState(false);
const senderInput = useRef();
useEffect(() => {
if (isModal) {
senderInput.current.focus();
}
}, [isModal]);
return (
<Pressable
onPress={() => {
setIsModal(true);
}}
>
<Text style={styles.blackText}>{sender}</Text>
</Pressable>
<Modal visible={isModal}>
<TextInput
value={sender}
onChangeText={text => {
setSender(text);
}}
maxLength={15}
ref={senderInput}
/>
</Modal>
</View>
);
};
생각해보니 setState()를 실행하면 적용되는 데 시간차가 생겼다. 지금도 setIsModal(true) 이후에 바로 연달아 focus()를 실행하는데, 그게 문제인가 싶어서 useEffect를 이용하여 isModal의 값이 바뀔 때 focus()를 실행하는 것으로 코드를 바꾸었다. 그랬더니 잘 실행된다!!
'TIL' 카테고리의 다른 글
[TIL-166] React Native (0) | 2022.04.14 |
---|---|
[TIL-165] React Native (0) | 2022.04.13 |
[TIL-163] React Native (0) | 2022.04.11 |
[TIL-162] 노마드코더 React Native #2.0~# (0) | 2022.04.09 |
[TIL-161] React Native (0) | 2022.04.08 |