인프런 커뮤니티 질문&답변

pysoon70님의 프로필 이미지
pysoon70

작성한 질문수

iOS/Android 앱 개발을 위한 실전 React Native - Basic

state 사용에 관하여..

작성

·

300

0

안녕하세요? 

질문 답변에 항상 감사드립니다. ..^^

실제 코딩을 하다보니 state 값을 control 하기가 참 힘드네요..ㅠㅠ

현재 회원가입화면에서 이메일주소와, 비밀번호, 확인 비밀번호를 입력받아 

올바른 입력인지 체크하는 단계입니다. 

그런데, 첫번째, 두번째 비밀번호 입력할때마다  첫번째, 두번째 비밀번호가 같은지 비교하여야하는데,

첫번째 비밀번호를 입력하여 setState 를 하고 바로 state값을 얻어와 2번째 비밀번호와 비교를 해야하는데. 

바로 적용된 state 값을 안 넘어오고 이전의 state값이 넘어옵니다.  (마지막 입력 글자는 state값으로 바로 안넘어옵니다.)

이럴때는 어떻게 해야하는지 참 난감합니다. 

TextInput onChangeText에서 입력값을 setState를 했는데도 다시 state값을 불러오면 바로 반영이 안되어 

내부 멤버변수로 그냥 사용을 했습니다. 

그런데, 이번에는 err_password 부분도 setState한 부분이 바로 반영이 되질 않습니다.  

이것도 멤버변수로 그냥 사용을 해야 하는지, 

아님 제가 모르는 부분이 있는지 꼭 답변 부탁드립니다. 

소스코드: 클래스 선언 부분)

class Join01_Start extends Component {

_emailTextInput = ''
_passwordTextInput = ''
_passwordTextInput2 = ''
constructor(props) {
super(props)
this.state = {

emailTextInput : '',
passwordTextInput : '',
passwordTextInput2 : '',
refEmail : React.createRef(),
refPassword : React.createRef(),
refPassword2 : React.createRef(),

err_email : false, //이메일입력 체크 에러 내용
err_password: false, //패스워드입력 체크 에러 내용
err_password2: false, //패스워드입력 체크 에러 내용

password_msg : '', //패스워드 입력 현황 메시지
password2_msg : '', //패스워드2 입력 현황 메시지

isNextDisable: true, //다음 버튼 활성화여부
}
}
//패스워드 입력 Validation
checkPasswordValidation = (passwordTextInput) => {
let reg = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$/;

if (reg.test(passwordTextInput) === false) { //잘못 입력시
this.setState({err_password : true})
} else { //에러없음
this.setState({err_password : false})
console.log('err_password false state setting')
}
console.log('check err_password', this.state.err_password )
this.displayErrPassword()
}
displayErrPassword = () => {
console.log('dis1', this._passwordTextInput, this.state.err_password, this._passwordTextInput2, this.state.err_password2)
if (this._passwordTextInput.length === 0 && this._passwordTextInput2.length === 0) {
this.setState({password_msg : ''})
this.setState({password2_msg : ''})
} else {
if (this.state.err_password) //비번1에 에러 있으면
this.setState({password_msg : '비밀번호가 올바르지 않습니다.'})
else {//비번1에 에러없으면
this.setState({password_msg : '사용가능한 비밀번호입니다.'})
}
}
}

소스코드: render() 함수 내부

{/* 비밀번호 */}
<View>
<View style={{ padding: 0, margin: 0, height: 50, flexDirection:'row', alignItems: 'center'}}>
<TextInput placeholder="비밀번호(영문,숫자,특수문자 포함 8~12자리)"
ref={(password) => {this.state.refPassword = password}}
autoFocus={false}
secureTextEntry={true}
keyboardType='default' //ios에서 키패드 안열리면 command + K 누르면 다음부터 보임
textContentType='oneTimeCode' //yellow strong 패스워드 방지하기
maxLength={12}
style={{paddingTop: 0, paddingBottom: 0 ,
width: '92%', height: '85%',
borderColor: '#5378DF',
borderBottomWidth : 1,
fontSize: 16, textAlign: 'left', marginRight: 5}}
value={this.state.passwordTextInput}
blurOnSubmit={false} //키보드 깜빡임 방지
returnKeyType='next'
onEndEditing={()=>console.log('pw1 endediting')}
onSubmitEditing={() => this.state.refPassword2.focus()}
onChangeText={(passwordTextInput) => {
this._passwordTextInput = passwordTextInput
this.setState({ passwordTextInput: passwordTextInput })
this.checkPasswordValidation(passwordTextInput)}}
/>

선생님의 경험담을 간절히 기다립니다..  

답변 3

0

pysoon70님의 프로필 이미지
pysoon70
질문자

선생님의 경험을 풀어주셔서 감사합니다. 

핵심은 state값을 가지고 와서 내부변수로 검증등을 처리하고 마지막에 state 값을 저장하는군요.. 

소중한 가르침을 주셔서 감사합니다.

가르침대로 잘 적용을 해보도록 하겠습니다.  

0

Wintho님의 프로필 이미지
Wintho
지식공유자

pysoon70,

안녕하세요. 지식공유자 Wintho입니다.

 

문의 주신 내용에 답변 드리겠습니다.

 

로그인 구현도 진행 중이신가 봅니다! 열정에 아낌없는 박수를 보냅니다!! :):)

 

개발자마다 구현하는 방법은 상이할 겁니다.

100명의 개발자가 있다면, 100개의 방법이 존재할 있지요.

 

저의 경우를 말씀드리자면, state에는 그대로상태 확인하기 위한 변수를 선언합니다.

예를 들면, 로그인의 경우는회원등록인지 로그인인지 단계를 구분하는 인자’, ‘에러가 발생했는지 여부등이 있겠지요.

state 비밀번호 첫번째/두번째 입력값을 할당해주어도 됩니다만, 첫번째 입력값과 두번째 입력값의 동일 여부 판단을 위해서는 로컬변수를 따로 설정해 두는 것이 편할 보입니다.

제가 잘못 이해했을 있습니다만, 패스워드 입력값을 state update하는 과정은 checkPasswordValidation 함수 이전이 아닌,

함수 내부 혹은 이후의 과정으로 두는 것이 좋을 합니다.

checkPasswordValidation 함수를 이용해서,

   1) 첫번째/두번째에 입력되는 패스워드 포맷의 유효성을 검증하신 ,

   2) 첫번째 입력값과 두번째 입력값의 동일성을 판단하는 함수를 따로 만들어둔 호출하셔서

   3) 입력값의 동일성 여부를 판단하시고

   4) state 최종값을 update하는

방향으로 구현하심이 어떨까 싶습니다.

 

TextInput onChangeText에서 입력값을 setState 했는데도 다시 state값을 불러오면 바로 반영이 안되어 

내부 멤버변수로 그냥 사용을 했습니다

그런데, 이번에는 err_password 부분도 setState 부분이 바로 반영이 되질 않습니다

=> 예시 코드를 적어봤는데 아래와 같이 시도해 보시길 바랍니다.

 

// state 선언

state = {

         form: {

                   password: {

                            value:””,

                            // ~~~

                   }

                   confirmPassword: {

                            value: “”,

                            // ~~~

                   }

         }

}

 

// render 함수 내부

<View>

         <Input

                   // ~~~

                   onChangeText={value=>this.updateInput(“password”, value)}

         />

 

         {this.confirmPassword()}

</View>

 

// updateInput 함수

updateInput = (name, value) => {

         let formCopy = this.state.form;

         formCopy[name].value = value;

 

         // ~~~~

 

         this.setState({

                   form: formCopy

         })

}

 

// confirmPassword 함수

confirmPassword = () => (

         <Input

                   value = {this.state.form.confirmPassword.value}

                   onChangeText = {value=>this.updateInput(“confirmPassword, value)}

         />

)

 

도움 되셨길 바랍니다.

감사합니다.

0

pysoon70님의 프로필 이미지
pysoon70
질문자

state 가 비동기로 작동을 한다는걸 알게되었습니다. 

그래서 setState한 후에 콜백함수를 사용해야한다는 걸 알게되었습니다. 

콜백함수를 사용하는 방법으로 해야하는게 맞는건지요? 

pysoon70님의 프로필 이미지
pysoon70

작성한 질문수

질문하기