기타 개발공부

생활코딩 리액트 2022 ver (2)

땅콩콩 2022. 7. 30. 02:37

* 본 포스팅은 생활코딩 리액트(2022)의 요약본입니다! 강의 링크는 포스팅 아래에 첨부하겠습니다 ^__^

 

**useState 추가개념

내가 상태로 만드려는 데이터가 원시타입일 경우에는 지금까지 하던것처럼 그냥 하면된다.

그런데 데이터가 범객체(객체, 배열 등)인 경우에는 좀 다른 방식으로 진행해야하는데

우선 데이터를 복제해놓고(newValue), 복제한 데이터를 변경한다.

다시말해 원본 데이터(value)를 바꾸는 것이 아니라, 복제본을 바꾸는 것이다.

그리고 setValue에 newValue를 넣어주면 그 때 비로소 컴포넌트가 재실행된다.

리액트는 setValue를 호출했을때, 원본 데이터와 새로운 데이터가 같은 데이터인지를 확인하고 만약 같다면 굳이 컴포넌트를 다시 렌더링하지 않는다. 그래서 배열과 같은 데이터를 사용할때 원본데이터로 그대로 진행할경우 렌더링이 안된다.

 

여기서 데이터를 복제할 때, 일반값의 경우 중괄호 안에 점 세개 {...value}, 배열의 경우 대괄호안에 점 세개 [...value]를 넣어 복제한다.

 

CREATE
function Create(props){
  return <article>
    <h2>Create</h2>
    <form onSubmit={event=>{
      event.preventDefault();
      const title = event.target.title.value;
      const body = event.target.body.value;
      props.onCreate(title, body);
    }}>
      <p><input type="text" name="title" placeholder="title"/></p>
      <p><textarea name="body" placeholder="body"></textarea></p>
      <p><input type="submit" value="Create"/></p>
    </form>
  </article>
}

function App() {
  const [mode, setMode] = useState('WELCOME');
  const [id, setId] = useState(null);
  const [nextId, setNextId] = useState(4);
  const [topics, setTopics] = useState([
    {id:1, title:'html', body:'html is ...'},
    {id:2, title:'css', body:'css is ...'},
    {id:3, title:'javascript', body:'javascript is ...'}
  ]);
  let content = null;
  if(mode==='WELCOME'){
    content = <Article title="WELCOME" body="Hello, WEB"></Article>
  }else if(mode==='READ'){
    let title, body = null;
    for(let i=0; i<topics.length; i++){
      if(topics[i].id===id){
        title = topics[i].title;
        body = topics[i].body;
      }
    }
    content = <Article title={title} body={body}></Article>
  }else if(mode==='CREATE'){
    content = <Create onCreate={(_title, _body)=>{
      const newTopic = {id:nextId, title:_title, body:_body}
      const newTopics = [...topics]
      newTopics.push(newTopic);
      setTopics(newTopics);
      setMode('READ');
      setId(nextId);
      setNextId(nextId+1);
    }}></Create>
  }
  return (
    <div>
      <Header title="WEB" onChangeMode={()=>{
        setMode('WELCOME');
      }}></Header>
      <Nav topics={topics} onChangeMode={(_id)=>{
        setMode('READ');
        setId(_id);
      }}></Nav>
      {content}
      <a href="/create" onClick={event=>{
        event.preventDefault();
        setMode('CREATE')
      }}>Create</a>
    </div>
  );
}

 

UPDATE

update의 경우, 기존 입력되어있던 값이 value로 주입되었을 때는 prop에서 state로 갈아탄다.

그리고 값이 바뀔때마다 바뀐 값을 state로 바꿔서 그 값을 다시 돌려줘야한다.

function Update(props){
  const [title, setTitle] = useState(props.title);
  const [body, setBody] = useState(props.body);
  return <article>
    <h2>Update</h2>
    <form onSubmit={event=>{
      event.preventDefault();
      const title = event.target.title.value;
      const body = event.target.body.value;
      props.onUpdate(title, body);
    }}>
      <p><input type="text" name="title" placeholder="title" value={title} onChange={event=>{
        setTitle(event.target.value);
      }}/></p>
      <p><textarea name="body" placeholder="body" value={body} onChange={event=>{
        setBody(event.target.value);
      }}></textarea></p>
      <p><input type="submit" value="Update"/></p>
    </form>
  </article>
}

function App() {
  const _mode = useState('WELCOME'); // 여기서 useState()의 매개변수는 state의 초기값이고, useState는 배열을 리턴함.
  const mode = _mode[0]; // mode를 통해 상태의 값을 읽을 수 있다.
  const setMode = _mode[1]; // setmode를 통해 mode의 값을 바꿀 수 있다.
  // 위의 세줄을 한줄로 줄이면 다음과 같다. > const [mode, setMode] = useState('WELCOME');
  const [id, setId] = useState(null);
  const [nextId, setNextId] = useState(4);
  const [topics, setTopics] = useState([
    {id:1, title:'html', body:'html is ...'},
    {id:2, title:'css', body:'css is ...'},
    {id:3, title:'javascript', body:'javascript is ...'}
  ]);
  let content = null;
  let contextControl = null;
  if(mode==='WELCOME'){
    content = <Article title="WELCOME" body="Hello, WEB"></Article>
  }else if(mode==='READ'){
    let title, body = null;
    for(let i=0; i<topics.length; i++){
      if(topics[i].id===id){
        title = topics[i].title;
        body = topics[i].body;
      }
    }
    content = <Article title={title} body={body}></Article>
    contextControl = <li><a href={"/update/"+id} onClick={event=>{
      event.preventDefault();
      setMode('UPDATE');
    }}>Update</a></li>
  }else if(mode==='CREATE'){
    content = <Create onCreate={(_title, _body)=>{
      const newTopic = {id:nextId, title:_title, body:_body}
      const newTopics = [...topics]
      newTopics.push(newTopic);
      setTopics(newTopics);
      setMode('READ');
      setId(nextId);
      setNextId(nextId+1);
    }}></Create>
  }
  else if(mode==='UPDATE'){
    let title, body = null;
    for(let i=0; i<topics.length; i++){
      if(topics[i].id===id){
        title = topics[i].title;
        body = topics[i].body;
      }
    }
    content = <Update title={title} body={body} onUpdate={(title, body)=>{
      const newTopics = [...topics]
      const updatedTopic = {id:id, title:title, body:body}
      for(let i=0; i<newTopics.length; i++){
        if(newTopics[i].id===id){
          newTopics[i] = updatedTopic;
          break;
        }
      }
      setTopics(newTopics);
      setMode('READ');
    }}></Update>
  }
  return (
    <div>
      <Header title="WEB" onChangeMode={()=>{
        setMode('WELCOME');
      }}></Header>
      <Nav topics={topics} onChangeMode={(_id)=>{
        setMode('READ');
        setId(_id);
      }}></Nav>
      {content}
      <ul>
      <li><a href="/create" onClick={event=>{
        event.preventDefault();
        setMode('CREATE')
      }}>Create</a></li>
      {contextControl}
      </ul>
    </div>
  );
}

 

DELETE
function App() {
  const _mode = useState('WELCOME'); // 여기서 useState()의 매개변수는 state의 초기값이고, useState는 배열을 리턴함.
  const mode = _mode[0]; // mode를 통해 상태의 값을 읽을 수 있다.
  const setMode = _mode[1]; // setmode를 통해 mode의 값을 바꿀 수 있다.
  // 위의 세줄을 한줄로 줄이면 다음과 같다. > const [mode, setMode] = useState('WELCOME');
  const [id, setId] = useState(null);
  const [nextId, setNextId] = useState(4);
  const [topics, setTopics] = useState([
    {id:1, title:'html', body:'html is ...'},
    {id:2, title:'css', body:'css is ...'},
    {id:3, title:'javascript', body:'javascript is ...'}
  ]);
  let content = null;
  let contextControl = null;
  if(mode==='WELCOME'){
    content = <Article title="WELCOME" body="Hello, WEB"></Article>
  }else if(mode==='READ'){
    let title, body = null;
    for(let i=0; i<topics.length; i++){
      if(topics[i].id===id){
        title = topics[i].title;
        body = topics[i].body;
      }
    }
    content = <Article title={title} body={body}></Article>
    contextControl = <>
    <li><a href={"/update/"+id} onClick={event=>{
      event.preventDefault();
      setMode('UPDATE');
    }}>Update</a></li>
    <li><input type="button" value="Delete" onClick={()=>{
      const newTopics = []
      for(let i=0; i<topics.length; i++){
        if(topics[i].id!==id){
          newTopics.push(topics[i]);
        }
      }
      setTopics(newTopics);
      setMode('WELCOME');
    }}/></li>
    </>
  }else if(mode==='CREATE'){
    content = <Create onCreate={(_title, _body)=>{
      const newTopic = {id:nextId, title:_title, body:_body}
      const newTopics = [...topics]
      newTopics.push(newTopic);
      setTopics(newTopics);
      setMode('READ');
      setId(nextId);
      setNextId(nextId+1);
    }}></Create>
  }
  else if(mode==='UPDATE'){
    let title, body = null;
    for(let i=0; i<topics.length; i++){
      if(topics[i].id===id){
        title = topics[i].title;
        body = topics[i].body;
      }
    }
    content = <Update title={title} body={body} onUpdate={(title, body)=>{
      const newTopics = [...topics]
      const updatedTopic = {id:id, title:title, body:body}
      for(let i=0; i<newTopics.length; i++){
        if(newTopics[i].id===id){
          newTopics[i] = updatedTopic;
          break;
        }
      }
      setTopics(newTopics);
      setMode('READ');
    }}></Update>
  }
  return (
    <div>
      <Header title="WEB" onChangeMode={()=>{
        setMode('WELCOME');
      }}></Header>
      <Nav topics={topics} onChangeMode={(_id)=>{
        setMode('READ');
        setId(_id);
      }}></Nav>
      {content}
      <ul>
      <li><a href="/create" onClick={event=>{
        event.preventDefault();
        setMode('CREATE')
      }}>Create</a></li>
      {contextControl}
      </ul>
    </div>
  );
}

 

https://www.youtube.com/watch?v=AoMv0SIjZL8&t=1s