어제 과제 이어서 만드는 input box에 입력하면 입력값 push
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>리액트 시간</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<link rel="stylesheet" href="./example6.css">
</head>
<body>
<div id="root">
</div>
<script type="text/babel">
class ComponentForm extends React.Component {
render() {
return (
<li className="comment-form">
<form onSubmit={this.props.onSubmit}>
<h4>댓글쓰기 <span>({this.props.length})</span></h4>
<span className="ps_box">
<input type="text" name="comment_text" placeholder="댓글내용을 입력해주세요." className="int" />
</span>
<input type="submit" value="등록" className="btn" />
</form>
</li>
)
}
}
class ComponentRow extends React.Component {
render() {
return (
<li>
<ul className="comment-row">
<li className="comment-id">{this.props.userid}</li>
<li className="comment-content">{this.props.content}</li>
<li className="comment-date">{this.props.date}</li>
</ul>
</li>
)
}
}
class CommentApp extends React.Component {
constructor(props) {
super(props)
this.state = {
comments: [
{ userid: 'asdf', content: '1111', date: '2021-06-30' },
{ userid: 'asdf', content: '2222', date: '2021-06-30' },
{ userid: 'asdf', content: '3333', date: '2021-06-30' }
]
}
}
//반복해서 만드는 함수
renderRow = () => {
let { comments } = { ...this.state }
console.log(comments)
return (
comments.map((v, k) => {
return(
<ComponentRow
key={k} //react가 요구하는 key값!
userid={v.userid}
content={v.content}
date={v.date}
/>
)
})
)
}
onSubmit=(e)=>{
e.preventDefault()
//e.target = event 가 발생한 DOM이 무엇이냐 = form element
console.log(e.target.comment_text.value)
console.log(e.target.querySelector('.int').value)
// form 안에 span이 있어서 못찾을까봐 className으로 찾음 !
let input=e.target.querySelector('.int').value
let obj = { userid: 'new', content: 'gg', date: '2021-06-30' }
//react는 push 하면 안됨!!
// setState에 위에 추가된 내용을 그려줘야함.. push하면 값을 넣어주지만
// render를 하지 않음 -> 방법 - 기존 값을 복사해오기
// copy해옴 - 불변성의 법칙 - 기존의 값을 그대로 복사해서 추가해라 !
let {comments} = {...this.state}
console.log(comments)
comments.push(obj)
console.log(comments)
this.setState({comments:comments})
e.target.reset();
}
render() {
return (
<ul className="comment">
<ComponentForm
length={this.state.comments.length}
onSubmit={this.onSubmit}
/>
{this.renderRow()}
</ul>
)
}
}
ReactDOM.render(
<CommentApp />,
document.querySelector('#root')
)
</script>
</body>
</html>
앞으로 공부할 것들
CRA 란 ? Creat React App
Node.js환경에서 npm 설치할 수 있다. 셋팅을 자동으로 세팅해주는 것 !
우리는 Components를 많아야 4개 만들었는데 Facebook은 약 20000개.............
코드 관리위해 라이브러리가 필요 !
React에 필요한 것들 === Babel, Webpack, React, ReactDOM -> 셋팅을 해주는 좋은 도구들
Babel, Webpack은 페이스북이 만든건 아니고 React만들 때 가져옴
Babel - 구문 짧게 만들어주고 JSX 사용하는 / <> </> 이것도 Bable에 의해 가능함. html안에서 코드변형할 때 사용
Webpack - JS build 파일 중 하나 / JS 파일 20000개를 ---함축--->1개로 만들어주는 build 해주는 아이 / 그 외 기능들도 많음 (아직 우리가 안씀)
React - React 구문 ex) React.Component{} , React.DOM()...
React-dom - 화면 그려주는 아이 / 결과물보여줄 때 html과 비교하여 다른 부분만 return하는 기능
다음 주부터 위의 라이브러리 직접적으로 개발환경 만드는걸 해볼 것 -> 눈으로 직접 어떻게 구동되는지 보기위함
Component
1. class component
옛날에 구현된 코드들은 class ---요즘 추세는 function으로 넘어가는중 --
2. function component
function이 좋다고 함 하지만 (각 회사 개발 스타일에 따라 다름 ) 예전 좋은 코드들은 class 라서 참고할 때 필요 !
=> 둘 다 배울 것. 다음 주부터 함수형으로 배울 것 / 둘 중 어떤걸 쓰더라도 일관성있게 하나만 쓰기 !
리액트 친구 = 리덕스
state 과 관련한 툴, state 불편한 점 : 최상위에서 아래로 내려가기 -> 리덕스 패키지로 조금 더 편하게 작업할 수 잇음
Next.js === 리액트
- 좀 더 쉽게 개발할 수 있는 툴
React Native
Application 코드 언어로 build
JS언어를 아이폰 (Swift) , 안드로이드(Kotlin) 언어로 바꾸는 기능
webview 기능 (어플 만들 때 브라우저만 만들고 웹페이지 띄우기 )
장점 : webpage 수정하면 어플 수정하기 쉬움 (어플 업데이트 쉽게 가능)
constructor(props){
super(props)
state = { }
}
요 구문을 위의 사진처럼 짧게 만들 수 있다. (babel 의 기능)
class App extends React.Component {
state={ // <- 요건 React Babel 환경에서만 ! JS는 다 써야함
text:'GOOD MORNING'
}
render() {
return (
<div>
{this.state.text}
</div>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
합성과 상속
어제의 코드를 Header부분을 만든다고 가정하고!
1. Header Component만들어 넣기
children을 쓰게되면 Header를 아래처럼 쓸 수 있다.
<div id="root"></div>
<script type="text/babel">
class Header extends React.Component{
render(){
return(
<ul className="comment">
{this.props.children}
</ul>
)
}
}
class App extends React.Component {
state={
text:'GOOD MORNING'
}
render() {
return (
<Header>
내용을 넣을 수 있습니다.
</Header>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
2. logo Component 만들고 넣어보기
class Logo extends React.Component {
render() {
return (
<li className="comment-form">
<form>
<h4>댓글쓰기 <span>(3)</span></h4>
<span className="ps_box">
<input type="text" placeholder="댓글내용을 입력해주세요." className="int" />
</span>
<input type="submit" value="등록" className="btn" />
</form>
</li>
)
}
}
class Header extends React.Component {
render() {
return (
<ul className="comment">
{this.props.children}
</ul>
)
}
}
class App extends React.Component {
state = {
text: 'GOOD MORNING'
}
render() {
return (
<Header>
<Logo />
내용을 넣을 수 있습니다.
</Header>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
3. Menu /MenuItem Component 만들기 + App Header Logo 아래에 넣어주기
class Logo extends React.Component {
render() {
return (
<li className="comment-form">
<form>
<h4>댓글쓰기 <span>(3)</span></h4>
<span className="ps_box">
<input type="text" placeholder="댓글내용을 입력해주세요." className="int" />
</span>
<input type="submit" value="등록" className="btn" />
</form>
</li>
)
}
}
class Header extends React.Component {
render() {
return (
<ul className="comment">
{this.props.children}
</ul>
)
}
}
class Menu extends React.Component {
render() {
return(
<>
<MenuItem/>
<MenuItem/>
<MenuItem/>
<MenuItem/>
</>
)
}
}
class MenuItem extends React.Component {
render() {
return (
<li>
<ul className="comment-row">
<li className="comment-id">web7722</li>
<li className="comment-content">안녕하세요 방가</li>
<li className="comment-date">20221-06-28</li>
</ul>
</li>
)
}
}
class App extends React.Component {
state = {
text: 'GOOD MORNING'
}
render() {
return (
<Header>
<Logo />
<Menu />
</Header>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
Header - logo, menu, util Component 만들어서 구현해보기
1. Header - children / Logo, Menu, Utill Component 기본 만들기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>리액트 시간</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<link rel="stylesheet" href="./example6.css">
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class Header extends React.Component{
render(){
return(
<div className="header">
{this.props.children}
</div>
)
}
}
class Logo extends React.Component{
render(){
return ;
}
}
class Menu extends React.Component{
render(){
return ;
}
}
class Utill extends React.Component{
render(){
return ;
}
}
class App extends React.Component{
render(){
return(
<Header>
<Logo />
<Menu />
<Utill />
</Header>
)
}
}
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
</script>
</body>
</html>
* React는 a tag를 쓰면 안됨 ! React는 SPA (Single Page Application)인데 a를 쓰면 의미가 없어짐 ! 나중에 다른거 쓰는걸 배울 예정
2. Logo(h1), Menu(ul,li), Utill(ul,li) 내용 채우기
class Logo extends React.Component{
render(){
return(
<h1>Logo</h1>
)
}
}
class Menu extends React.Component{
render(){
return(
<ul>
<li>menu1</li>
<li>menu2</li>
<li>menu3</li>
<li>menu4</li>
</ul>
)
}
}
class Utill extends React.Component{
render(){
return(
<ul>
<li>로그인</li>
<li>회원가입</li>
</ul>
)
}
}
3. Utill 로그인/회원가입 -----> 로그아웃/ 회원정보 표현하기 (isLogin)
조건부 렌더링 - App state = isLogin:false 추가
return 안에는 함수나 많은 내용이 들어가는건 비추 !
class Utill extends React.Component {
login = () => {
return (
<>
<li>로그인</li>
<li>회원가입</li>
</>
)
}
logout = () => {
return (
<>
<li>로그아웃</li>
<li>회원정보</li>
</>
)
}
render() {
return (
<ul>
{this.props.isLogin ? this.logout() : this.login()}
</ul>
)
}
}
class App extends React.Component {
state = {
isLogin: false,
}
render() {
return (
<Header>
<Logo />
<Menu />
<Utill isLogin={this.state.isLogin} />
</Header>
)
}
}
ㄷ.
새로운 html 생성 + App Component 기본 세팅
App이 아닌 Login 에서 상태값을 갖기 ---> App에 전달
2. LoginBox Component 에 상태 userid, userpw / return form (input 3) 만들기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>리액트 시간</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<link rel="stylesheet" href="./example6.css">
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class LoginBox extends React.Component{
state={
userid:'',
userpw:''
}
render(){
return(
<form>
<input type="text" />
<input type="password"/>
<button type="submit" >로그인</button>
</form>
)
}
}
class App extends React.Component{
state={
}
render(){
return(
<LoginBox />
)
}
}
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
</script>
</body>
</html>
3. LoginBox
class LoginBox extends React.Component {
state = {
userid: '',
userpw: ''
}
render() {
return (
<form>
<input
type="text"
placeholder="아이디를 입력해주세요"
value={this.state.userid}
name="userid"
/>
<input
type="password"
placeholder="비번을 입력해주세요"
value={this.state.userpw}
name="userpw"
/>
<button type="submit" >로그인</button>
</form>
)
}
}
-> 내용은 뜨지만 오류 있다.
4. input box에 넣은 값을 onChange로 바꿔주기 (오류 수정)
class LoginBox extends React.Component {
state = {
userid: '',
userpw: ''
}
handleChange=(e)=>{
//들어오는 input name 대로 바꾸기 위함 (input이 너무 많을 때)
this.setState({[e.target.name]:e.target.value})
}
render() {
return (
<form>
<input
type="text"
placeholder="아이디를 입력해주세요"
value={this.state.userid}
name="userid"
onChange={this.handleChange}
/>
<input
type="password"
placeholder="비번을 입력해주세요"
value={this.state.userpw}
name="userpw"
onChange={this.handleChange}
/>
<button type="submit" >로그인</button>
</form>
)
}
}
5. 페이지 이동없이 값이 사라지게 만들기
class LoginBox extends React.Component {
state = {
userid: '',
userpw: ''
}
handleChange=(e)=>{
//들어오는 input name 대로 바꾸기 위함 (input이 너무 많을 때)
this.setState({[e.target.name]:e.target.value})
}
handleSubmit=(e)=>{
e.preventDefault()
this.setState({
userid:'',
userpw:'',
})
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input
type="text"
placeholder="아이디를 입력해주세요"
value={this.state.userid}
name="userid"
onChange={this.handleChange}
/>
<input
type="password"
placeholder="비번을 입력해주세요"
value={this.state.userpw}
name="userpw"
onChange={this.handleChange}
/>
<button type="submit" >로그인</button>
</form>
)
}
6. App에 값 전달하기 -> console.log 찍힌거 - > App Component에서 찍혔다는게 중요 !
class LoginBox extends React.Component {
state = {
userid: '',
userpw: ''
}
handleChange=(e)=>{
//들어오는 input name 대로 바꾸기 위함 (input이 너무 많을 때)
this.setState({[e.target.name]:e.target.value})
}
handleSubmit=(e)=>{
e.preventDefault()
this.props.onCreate(this.state) // 받음 by App 로그인 버튼 누른 시점에 넘겨주기
this.setState({ //넘겨주고 reset
userid:'',
userpw:'',
})
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input
type="text"
placeholder="아이디를 입력해주세요"
value={this.state.userid}
name="userid"
onChange={this.handleChange}
/>
<input
type="password"
placeholder="비번을 입력해주세요"
value={this.state.userpw}
name="userpw"
onChange={this.handleChange}
/>
<button type="submit" >로그인</button>
</form>
)
}
}
class App extends React.Component {
loginInfo=(data)=>{
console.log(data)
}
render() {
return (
<LoginBox onCreate={this.loginInfo} />
)
}
}
하위 -> 상위로 값을 넘김
위에서 만든 <Header>와 합치기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>리액트 시간</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<link rel="stylesheet" href="./example6.css">
<style>
.header{
display: inline-block;
float:left
}
.header>li{
display: inline-block;
float:left
}
.loginbox{
width:1000px;
height:200px;
display: block;
}
</style>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class Header extends React.Component {
render() {
return (
<div className="header">
{this.props.children}
</div>
)
}
}
class Logo extends React.Component {
render() {
return (
<h1 className="header">Logo</h1>
)
}
}
class Menu extends React.Component {
render() {
return (
<ul className="header">
<li>menu1</li>
<li>menu2</li>
<li>menu3</li>
<li>menu4</li>
</ul>
)
}
}
class Utill extends React.Component {
login = () => {
return (
<>
<li>로그인</li>
<li>회원가입</li>
</>
)
}
logout = () => {
return (
<>
<li>로그아웃</li>
<li>회원정보</li>
</>
)
}
render() {
return (
<ul className="header">
{this.props.isLogin ? this.logout() : this.login()}
</ul>
)
}
}
class LoginBox extends React.Component {
state = {
userid: '',
userpw: '',
}
handleChange=(e)=>{
//들어오는 input name 대로 바꾸기 위함 (input이 너무 많을 때)
this.setState({[e.target.name]:e.target.value})
}
handleSubmit=(e)=>{
e.preventDefault()
this.props.onCreate(this.state) // 받음 by App 로그인 버튼 누른 시점에 넘겨주기
this.setState({ //넘겨주고 reset
userid:'',
userpw:'',
})
}
login_form = () =>{
return (
<form onSubmit={this.handleSubmit} >
<input
type="text"
placeholder="아이디를 입력해주세요"
value={this.state.userid}
name="userid"
onChange={this.handleChange}
/>
<input
type="password"
placeholder="비번을 입력해주세요"
value={this.state.userpw}
name="userpw"
onChange={this.handleChange}
/>
<button type="submit" >로그인</button>
</form>
)
}
logout_btn = () =>{
return(
<>
<button type="submit" onClick={this.props.loginFn} >로그아웃</button>
</>
)
}
render() {
return (
<div className="loginbox">
{this.props.isLogin ? this.logout_btn() : this.login_form() }
</div>
)
}
}
class App extends React.Component {
state = {
isLogin: false,
}
loginInfo=(data)=>{
console.log(data)
if (data.userid =='admin' && data.userpw=='admin'){
this.setState({isLogin:true})
}
}
loginFn=()=>{
this.setState({isLogin:!this.state.isLogin})
}
render() {
return (
<>
<Header>
<Logo />
<Menu />
<Utill isLogin={this.state.isLogin} />
</Header>
<LoginBox
onCreate={this.loginInfo}
isLogin={this.state.isLogin}
loginFn={this.loginFn}
/>
</>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
</script>
</body>
</html>
'블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기' 카테고리의 다른 글
[76-77일차 복습] 리액트 댓글 추가 수정 삭제 / React 합성과 상속 (0) | 2021.07.01 |
---|---|
[77일차]20210701 React 댓글 수정 삭제 / 리액트로 생각하기 / 합성과 상속 (0) | 2021.07.01 |
[75일차 복습] React, state 끌어 올리기 / 리액트 구구단 (0) | 2021.06.29 |
[75일차] 20210629 React 리액트 구구단 출력하기 (0) | 2021.06.29 |
[74일차 복습] 리액트란? 리액트 기초 배우기 / React CDN 링크 (0) | 2021.06.28 |