props와 state는 렌더링 결과물에 영향을 주는 정보를 가지는 일반 javascript 객체다.
컴포넌트의 속성(property)으로 외부로부터 전달받는 변하지 않는 값을 의미하며, 웹 앱에서 해당 컴포넌트가 가진 속성에 해당한다.
props는 어떤 타입의 값도 넣어 전달할 수 있도록 객체 형태를 가진다.
props는 변경되지 않는 읽기 전용 객체다.
function Parent() {
  return (
    <div>
      <h1>parent</h1>
      <Child me='child'/>
    //<Child>child</Child>
    </div>
  );
};function Child(props) {
  return (
    <div>{props.me}</div>
  //<div>{props.chilren}</div> => props.children은 해당 컴포넌트의 태그 사이 value에 접근할 수 있다.
  );
};컴포넌트 내부에서 변할 수 있는 값으로 컴포넌트 내에서 관리된다.
useState는 상태 유지 값과 그 값을 갱신하는 함수를 배열 형태로 반환한다.
import {useState} from 'react';
const [state, setState] = useState();
useState에 인자는 state의 초기값으로 전해진다. 첫 렌더링 시 한번만 적용된다.
state의 변경은 렌더링을 불러오지만 갱신함수 없이 직접적으로 변경을 시도하면 렌더링이 작동하지 않거나 state변경이 이루어지지 않는다.
상태값 갱신
갱신 함수에 들어온 값으로 state가 '변경'된다.
import {useState} from 'react';
function App() {
  const [count, setCount] = useState(0);
  
  function handleClick() {
    setCount(count++);
  }
  
  return (
  	<div>{count}</div>
    <button onClick={handleClick}>count up</button> {/*누를때마다 count가 증가*/}
  )
}
 이벤트의 이름은 카멜케이스로 작성한다.
함수를 직접 작성하거나 정의된 함수를 할당한다.
<button onClick={handleCount}>count up</button>
<button onClick={()=>setCount(count++)}>count up</button>
onClick
element를 클릭 했을때 발생하는 이벤트 ex) <button> 등
onChange
from element의 사용자 입력값이 갱신 되었을 때 발생하는 이벤트 ex) <input>, <textarea>, <select> 등
import {useState} from 'react';
function App() {
  const [text, setText] = useState('');
  const [pick, setPick] = useState(')
  
  function handleChange(e) {
    setChange(e.target.value);
  }
  
  const handleSelect = e => {
    setPick(e.target.value);
  }
  
  const word = [a, b, c, d];
  const options = word.map(x=><optoin>{x}</option>);
 
  return (
  	<input type='text' onChange={handleChange}></input>
   <select onChange={handleSelect}>{options}</select>
 )
}
test의 마지막 단계인 새로운 tweet 추가는 state와 eventhandler를 통해서 구현한다. tweets 컴포넌트에 새롭게 추가할 tweet과 작성자의 정보 들을 담을 객체를 생성하고, dummyData를 초기값으로 가지는 state를 선언해 구현한다.
import React, {useState} from 'react';
const Tweet = ({tweet}) => {
  {/*Tweet의 인자는 props로 받아서 const tweet=props.tweet으로 사용할 수도 있다.*/}
  {/*날짜를 한국식으로 변경*/}
  const parsedDate = new Date(tweet.createdAt).toLocaleDateString('ko-kr');
  {/*props로 데이터를 받아와 필요한 요소들을 용도에 맞게 사용*/}
  return (
    <li className="tweet" id={tweet.id}>
      <div className="tweet__profile">
        <img src={tweet.picture} /> {/*사용자 사진*/}
      </div>
      <div className="tweet__userInfo--wrapper">
        <span className="tweet__username">{tweet.username}</span> // {/*사용자 이름*/}
        <span className="tweet__createdAt">{parsedDate}</span> // {/*생성날짜*/}
      </div>
       <div className="tweet__message">{tweet.content}</div> {/*사용자가 작성한 메세지*/}
      </div>
    </li>
  );
};
const Tweets = () => {
  // tweet데이터들을 담을 state를 만든다.
  const [tweets, setTweets] = useState(dummyTweets);
  
  // 사용자가 tweet메세지를 작성하고 제출 버튼을 누르면 tweet을 추가하는 이벤트 핸들러
  const handleButtonClick = (event) => {
    const tweet = {
      id: tweets.length+1,
      username: username, //사용자의 이름
      picture: 'https://randomuser.me/api/portraits/men/98.jpg', // 사용자의 이미지
      title: 'new Tweet',
      content: msg, // 사용자가 작성한 tweet 메세지
      createdAt: new Date().toLocaleDateString('ko-KR'), // 작성한 날짜
      updatedAt: new Date().toLocaleDateString('ko-KR'), // 업로드한 날짜
    };
    const newTweets = [tweet, ...tweets]; // 새로운 tweet을 기존의 tweets 목록의 앞에다가 추가
    setTweets(newTweets);
  };
  return (
    <React.Fragment>
      {/*..중략*/}
        <div className="tweetForm__submitIcon"> </div>
      {/*tweet를 제출할 버튼 onclick에 위에서 정의한 함수를 할당*/}
          <button className="tweetForm__submitButton" onClick={handleButtonClick}>Tweet</button>
        </div>
       {/*..중략*/}
      <ul className="tweets">
      {/*map()으로 존재하는 데이터 개수만큼 Tweet 컴포넌트를 생성 */}
        {filters.map(tweet=><Tweet key={tweet.id} tweet={tweet} />>)}</ul>
      <Footer />
    </React.Fragment>
  );
};
export default Tweets;