[React Native] 에러 처리

Nadan
Nadan Dev Blog

에러 처리

에러도 state를 통해 처리하면 화면에 렌더링하기 좋다. 에러가 오면 화면에 문제가 있음을 알려주자

-> 예제 변경

{ errMsg ? <Text>{errMsg}</Text> : null }
<>
    <SearchBar 
        term={term} 
        onTermChange={setTerm}
        onTermSubmit={() => searchAPI(term)}  />
    {errMsg ? <Text>{errMsg}</Text> : null}
    <Text>We have found {results.length} results</Text>
    <ScrollView>
        <ResultsList results={filterResultsByPrice('$')} title="Cost Effective"/>
        <ResultsList results={filterResultsByPrice('$$')} title="Bit Pricier"/>
        <ResultsList results={filterResultsByPrice('$$$')} title="Big Spender"/>
    </ScrollView>
</>

Docs

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Error

네트워크 에러 이해

서버 에러 처리는 response에서 코드를 받아서 처리해야 함. 즉, 일단 서버에서 냅다 에러를 던지는 게 아니라 에러에 따라 분류해서 response를 만들어 줘야 함

예1) Screen에서 발생한 오류 처리

-> 예제 변경

const SearchScreen = () => {

    const [term, setTerm] = useState('');
    const [results, setResults] = useState([]); // 배열로 리턴될 것을 예상
    const [errMsg, setErrMsg] = useState('');

    const searchAPI = async () => {
        try {
            const response = await yelp.get('/search', {
                params: {
                    term,
                    location: 'san jose',
                    limit: 50
                }
            });
            setResults(response.data.businesses);
        } catch(err) {
            setErrMsg('Something went wrong!');
        }
    }

    return (
        <View style={styles.background}>
            <SearchBar 
                term={term} 
                onTermChange={setTerm}
                onTermSubmit={() => searchAPI()}  />
            { errMsg ? <Text>{errMsg}</Text> : null }
            <Text>We have found {results.length} results</Text>
        </View>
    )
}

예2) Context상에서 발생항 오류 처리

-> 예제 변경해줘야 함

AuthContext.js

const authReducer = (state, action) => {
    switch (action.type) {
        case 'add_error':
            return { ...state, errorMessage: action.payload }
        default:
            return state;
    }
};

const signup = (dispatch) => {
    return async ({ email, password }) => {
        try {
            const response = await trackerAPI.post('/signup', { email, password })
        } catch (err) {
            dispatch({ type: 'add_error', payload: 'Something went wrong with sign up'});
        }
    }
}

SignUpScreen.js

const SignUpScreen = ({ navigation }) => {

    const { state, signup } = useContext(AuthContext);
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');

    return (
        <View style={styles.container}>
            <Spacer>
                <Text h3>Sign Up for Tracker</Text>
            </Spacer>
            <Input 
                autoCapitalize="none"
                autoCorrect={false}
                label="Email"
                value={email}
                onChangeText={(newText) => setEmail(newText)}/>
            <Input 
                secureTextEntry
                autoCapitalize="none"
                autoCorrect={false}
                label="Password"
                value={password}
                onChangeText={(newText) => setPassword(newText)}
                errorMessage={state.errorMessage ? <Text style={styles.errorMessage}>{state.errorMessage}</Text> : null}
                // errorMessage={state.errorMessage}
            />
            <Spacer>
                <Button 
                    title="Sign Up"
                    onPress={() => signup({ email, password})}
                />
            </Spacer>
            
        </View>
    );
}