キャンプ2日目
42700 ワード
👍 本日のレッスン内容
なぜReact,React素子(State)を学ぶのか
👍 どうしてReactを勉強するの?
👍 はんのうそし
コンポーネントにより、UIまたは機能の再利用が容易になります.
👍 React state
state:構成部品で使用される変数
setState:構成部品で使用する変数を置き換える機能
useState:構成部品で使用する変数を作成する機能
userStateはreactからインポートする必要があります.
2日目テスト(状態練習)
index.js
import {Wrapper1,Wrapper2,Wrapper3,HeaderHeader,Header,Main,MainId,Id,IdInput,Footer
,MainPw,HeaderTitle, Pw, PwInput, LoginButton,TalkButton
,FooterMain,FooterFont,TalkLogin,Error} from '../../../styles/02-login'
import {useState} from 'react'
export default function BoardsNewPage(){
const [ email, setEmail ] = useState()
const [ pass, setPass ] = useState()
const [ emailError, setEmailError ] = useState()
const [ passError, setPassError ] = useState()
function onChangeEmail(event) {
setEmail(event.target.value)
}
function onChangePass(event) {
setPass(event.target.value)
}
function onClickSignup() {
if(email === "" || !email.includes("@")) {
setEmailError("이메일을 확인해 주세요")
}
if(pass === "" || pass.length < 8) {
setPassError("8~16자의 영문,숫자,특수문자만 사용가능합니다.")
}
}
return (
<Wrapper1>
<Wrapper2 >
<HeaderHeader></HeaderHeader>
<Wrapper3>
<Header>
<img src="/images/photo10.png"/>
<HeaderTitle>잇츠로드</HeaderTitle>
</Header>
<Main>
<MainId>
<Id>
<IdInput type = "text" placeholder="이메일을 입력해 주세요" onChange={onChangeEmail}/>
<img src="/images/photo11.png"/>
</Id>
<hr />
<div>
<Error>{emailError}</Error>
</div>
</MainId>
<MainPw>
<Pw>
<PwInput type = "password" placeholder="비밀번호를 입력해 주세요" onChange={onChangePass}/>
<img src="/images/photo11.png"/>
</Pw>
<hr/>
<div>
<Error>{passError}</Error>
</div>
</MainPw>
</Main>
<Footer>
<LoginButton onClick={onClickSignup}>로그인</LoginButton>
<FooterMain>
<FooterFont>이메일 찾기</FooterFont>
<FooterFont>|</FooterFont>
<FooterFont>비밀번호 찾기</FooterFont>
<FooterFont>|</FooterFont>
<FooterFont>회원가입</FooterFont>
</FooterMain>
<TalkButton>
<img src="/images/photo12.png"/>
<TalkLogin>카카오톡으로 로그인</TalkLogin>
</TalkButton>
</Footer>
</Wrapper3>
</Wrapper2>
</Wrapper1>
)
}
02-login.jsimport styled from '@emotion/styled'
export const Wrapper1 = styled.div`
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
`
export const Wrapper2 = styled.div`
width: 640px;
height: 1138px;
background-color: skyblue;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: solid 1px black;
background-image: url("/images/photo13.png");
`
export const HeaderHeader = styled.div`
width: 640px;
height: 43px;
border : solid 1px black;
`
export const Wrapper3 = styled.div`
width: 540px;
height: 1095px;
`
export const Header = styled.div`
width: 540px;
height: 400px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
`
export const HeaderTitle = styled.span`
font-size: 60px;
color: white;
`
export const Main = styled.div`
width: 540px;
height: 300px;
/* background-color: blue; */
`
export const MainId = styled.div`
width: 540px;
height: 90px;
`
export const Id = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
`
export const IdInput = styled.input`
width:400px;
height: 30px;
border: none;
background-color:transparent;
color: white;
`
export const MainPw = styled.div`
width: 540px;
height: 90px;
`
export const Pw = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
`
export const PwInput = styled.input`
width:400px;
height: 30px;
border: none;
background-color:transparent;
color: white;
`
export const Footer = styled.div`
width: 540px;
height: 350px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
`
export const LoginButton = styled.button`
width: 540px;
height: 76px;
border-radius: 38px;
opacity: 0.6;
background-color: #ff1b6d;
font-size: 26px;
color: white;
`
export const TalkButton = styled.button`
width: 540px;
height: 76px;
border: 1px solid yellow;
border-radius: 38px;
background-color:transparent;
font-size: 26px;
color: yellow;
`
export const FooterMain = styled.div`
width: 400px;
height: 30px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
`
export const FooterFont = styled.span`
size: 20px;
color: white;
`
export const TalkLogin = styled.span`
margin-left: 10px;
`
export const Error = styled.div`
color: red;
`
2日目
index.js
import{ Wrapper1, Wrapper,Title, IdInput,TextInput,Header, InputText, Main, MainInput, Address,
AddressInput, AddressButton, YouTube, Picture,
PictuerButton, PictureDiv,MainSettings, FooterButton,
AddressBox,MiniTitle,ErrorMessage} from '../../../styles/BoardsNew.styles'
import {useState} from 'react'
export default function BoardsNewPage(){
const [ name, setName ] = useState()
const [ pass, setPass ] = useState()
const [ title, setTitle ] = useState()
const [ contents, setContents ] = useState()
const [ nameError, setNameError ] = useState()
const [ passError, setPassError ] = useState()
const [ titleError, setTitleError ] = useState()
const [ contentsError, setContentsError ] = useState()
function onChangeName(event) {
setName(event.target.value)
}
function onChangePass(event) {
setPass(event.target.value)
}
function onChangeTitle(event) {
setTitle(event.target.value)
}
function onChangeContents(event) {
setContents(event.target.value)
}
function onClickSignup() {
if(name === ("")) {
setNameError("이름을 작성해주세요.")
}
if(pass === ("")) {
setPassError("비밀번호를 작성해주세요.")
}
if(title === ("")) {
setTitleError("제목을 작성해주세요.")
}
if(contents === ("")) {
setContentsError("내용을 작성해주세요.")
}
}
return (
<Wrapper1>
<Wrapper>
<Title>게시물 등록</Title>
<IdInput>
<div>
<div>
<MiniTitle>작성자</MiniTitle>
</div>
<TextInput type="text" placeholder="이름을 적어주세요" onChange={onChangeName}/>
<ErrorMessage>{nameError}</ErrorMessage>
</div>
<div>
<div>
<MiniTitle>비밀번호</MiniTitle>
</div>
<TextInput type="password" placeholder="비밀번호를 입력해주세요" onChange={onChangePass} />
<ErrorMessage>{passError}</ErrorMessage>
</div>
</IdInput>
<Header>
<MiniTitle>제목</MiniTitle>
<InputText type="text" placeholder="제목을 입력하세요" onChange={onChangeTitle}/>
<ErrorMessage>{titleError}</ErrorMessage>
</Header>
<Main>
<MiniTitle>내용</MiniTitle>
<MainInput type="text" placeholder="내용을 작성해주세요" onChange={onChangeContents}/>
<ErrorMessage>{contentsError}</ErrorMessage>
</Main>
<Address>
<MiniTitle>주소</MiniTitle>
<AddressBox>
<AddressInput type="text"/>
<AddressButton>우편번호 검색</AddressButton>
</AddressBox>
<div>
<InputText type="text"/>
</div>
<div>
<InputText type="text"/>
</div>
</Address>
<YouTube>
<div>
<MiniTitle>유튜브</MiniTitle>
</div>
<div>
<InputText type="text" placeholder="링크를 복사해주세요"/>
</div>
</YouTube>
<Picture>
<div>
사진첨부
</div>
<PictureDiv>
<PictuerButton>
<span>+</span>
<span>Upload</span>
</PictuerButton>
<PictuerButton>
<span>+</span>
<span>Upload</span>
</PictuerButton>
<PictuerButton>
<span>+</span>
<span>Upload</span>
</PictuerButton>
</PictureDiv>
</Picture>
<MainSettings>
메인설정
<div>
<input type="radio" name="settings"/>유튜브
<input type="radio" name="settings"/>사진
</div>
</MainSettings>
<FooterButton onClick={onClickSignup}>등록하기</FooterButton>
</Wrapper>
</Wrapper1>
)
}
BoardsNew.styles.jsimport styled from '@emotion/styled'
export const Wrapper1 = styled.div`
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
`
export const Wrapper = styled.div`
border: solid 1px black;
width: 1200px;
height: 1715px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
`
export const Title = styled.h1`
margin-top: 50px;
`
export const IdInput = styled.div`
width: 996px;
height: 130px;
display: flex;
flex-direction: row;
justify-content: space-between;
/* align-items: center; */
`
export const TextInput = styled.input`
width: 486px;
height: 52px;
margin-top: 10px;
`
export const Header = styled.div`
width: 996px;
height: 120px;
display: flex;
flex-direction: column;
`
export const InputText = styled.input`
width: 996px;
height: 52px;
border: solid 1px black;
margin-top: 10px;
`
export const Main = styled.div`
width: 996px;
height: 530px;
display: flex;
flex-direction: column;
`
export const MainInput = styled.input`
width: 996px;
height: 480px;
border: solid 1px black;
`
export const Address = styled.div`
width: 996px;
height: 200px;
display: flex;
flex-direction: column;
justify-content: space-between;
`
export const AddressBox = styled.div`
width: 210px;
display: flex;
flex-direction: row;
justify-content: space-between;
`
export const AddressInput = styled.input`
width: 77px;
height: 52px;
`
export const AddressButton = styled.button`
width: 124px;
height: 52px;
background-color: black;
color: white;
`
export const YouTube = styled.div`
width: 996px;
height: 80px;
display: flex;
flex-direction: column;
justify-content: space-between;
`
export const Picture = styled.div`
width: 996px;
height: 120px;
display: flex;
flex-direction: column;
justify-content: space-between;
`
export const PictureDiv = styled.div`
width: 270px;
display: flex;
flex-direction: row;
justify-content: space-between;
`
export const PictuerButton = styled.div`
width: 78px;
height: 78px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #BDBDBD;
`
export const MainSettings = styled.div`
width: 996px;
height: 50px;
display: flex;
flex-direction: column;
justify-content: space-between;
`
export const FooterButton = styled.button`
width: 179px;
height: 52px;
background-color: #FFD600;
margin-bottom: 50px;
border: none;
`
export const MiniTitle = styled.span`
margin-bottom: 10px;
`
export const ErrorMessage = styled.div`
color:red;
`
Reference
この問題について(キャンプ2日目), 我々は、より多くの情報をここで見つけました https://velog.io/@sanghyeok_lee/캠프2일차-8aucqqu1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol