구현해야할 기능은
새글을 입력하고 버튼을 누르면 해당 내용이 아래의 리스트에 추가 되는 것.
시작앞서서
extends React.Component
//extends 부분에 React.Component의 React는
import{component}를 쓰면 생략이 가능하게 사용가능하다.
구현해야할 react를 컴포넌트 단위로 나눠보는 것이 중요하다.
트위틀러는 모든 객체들의 부모컴포넌트이다.
newTweetForm은 textarea부분에 값 넘겨주는 것.
singletweet에서는 엔터눌렀을 때의 내용이 추가 되는 것
기본적으로 react에서 태그의 class 이름을 줄 때는
<div className="Jack">
</div>
className으로 줘야한다.
constructor(props) {
super(props);
this.state = {
tweets: [
{ writer: "김코딩", createdAt: "2021-05-10", body: "Hi react" },
{ writer: "박해커", createdAt: "2021-05-11", body: "재미있다 리액트" }
]
};
컨스트럭터는 초기에 설정해줄 것 들을 적어줘야한다.
기본적으로 기본 트위 2개가 설정되어 있는 컨셉이여서
이것을 하드코딩식으로 적어줘야한다.
지금은 this.state를 이용하여 작성하고 추가 될 것이 있다면 tweets 배열안에 새로운 객체를 추가하는 식으로 작성하게 할것이다.
근데 만약 이렇게 작성하지 않았다면
직접 SingleTweet부분에 값을 props로 넣어주고 이것을
singletweet.js에서 값을 받아 표시해줘야할것이다.
이 부분에서 props로 넣어준 값을 가져와 {props.writer}로 값을 받아오면
this.state처럼 똑같이 표시된다.
파라미터를 구조 분해 문법을 통해 좀 더 간단하게 받아 올 수도 있다.
<SingleTweet>
여기의 값은 어떻게 받아올까요?
</SingleTweet>
컴포넌트 사이의 값은 {props.children}으로 받아 올 수 있다.
근데 지금은 처음 작성하던 식인 this.state로 작성할 것이다.
왜냐면 추가할 때마다 값이 변해야함으로 지금 이런식으로 props로 하드코팅하면 값을 변경 할 수가없다.
constructor(props) {
super(props);
this.state = {
tweets: [
{ writer: "김코딩", createdAt: "2021-05-10", body: "Hi react" },
{ writer: "박해커", createdAt: "2021-05-11", body: "재미있다 리액트" }
]
};
render() {
return (
<div>
{this.state.tweets.map((t) => (
<SingleTweet writer={t.writer} createdAt={t.createdAt}>
{t.body}
</SingleTweet>
))}
</div>
</div>
);
}
리액트를 사용하기 위해서 immutable한 방식으로 작성해줘야하고,
map대신 for문을 쓰게되면 리턴값이 복잡해져서 map을 추천
render()를 통해 this.state.tweets의 초기화 해준 값 뿐만아니라 새로 추가도니 것도 render()될 때마다 새로 쭉 뿌려주게 된다.
여기에 텍스트와 버튼을 추가해보면
constructor(props) {
super(props);
this.state = {
tweets: [
{ writer: "김코딩", createdAt: "2021-05-10", body: "Hi react" },
{ writer: "박해커", createdAt: "2021-05-11", body: "재미있다 리액트" }
],
newTweet: ''
};
this.handleChange=this.handleChange.bind(this);
//this가 상위 class Twittler를 가르키지 못해서 항상 메서드 쓰면 이 문장을 적용해줘야함.
this.handleClick=this.hanldeClick.bind(this);
};
handleClick(){
let newTweet ={
writer: "김코딩", //일단 고정 이름
createdAt: new Date().toISOString().substring(0, 10), //현재 시간 2020-05-11 처럼 10자리로 끊어서 표현해줌
body: this.state.newTweet
};
this.setState((prevState)=>{
return (
tweets [...prevState.tweets, newTweet]
//기존 트위에 있던 정보와함께 추가할 것도 다 표시
)}
};
handleChange(event){
let tweetbody = event.target.value;
//보통 textarea와 연결해서 많이 쓴다. event.target을 통해 인풋안의 입력 값을 가져온다.
this.setState({newTweet: tweetbody});
//setState를 통해 값 변경
}
render() {
return (
<textarea value={this.state.newTweet}></textarea>
<button onClick={this.handleClick}>새 글 쓰기</button>
<div>
{this.state.tweets.map((t) => (
<SingleTweet writer={t.writer} createdAt={t.createdAt}>
{t.body}
</SingleTweet>
))}
</div>
</div>
);
}
이 후에 liftting state up을 하고
처음 컴포넌트 구현식을 쓰기위해서
newTweetForm을 만들어 위치를 시켜야 하는데
완성된 codeSandbox에서 한번 살표보자
<NewTweetForm submitTweet={this.addNewTweet} />
어떤식으로 가져올까를 중점적으로 보자
CodeSandbox
https://codesandbox.io/s/nameless-dew-q41en?file=/src/App.js