TIL_220727

nevermind·2022년 7월 28일
0
post-custom-banner

리액트 개인과제 기능 구현

막막했었고 이제 리액트의 구조가 아주 조금씩 보이는듯하지만 어렵다
🥝이름을 잘 정해야겠다 (변수나 map함수 돌릴 때 이름들이나)

useState

  • 하위 컴포넌트의 변화를 어떻게 받을 것인가? useState를 사용하여 호출할 수 있다.
  • contents는 데이터, setContents는 값을 바꿔주는 함수
여기는 <Layout> 컴포넌트

    const [contents, setContents] = useState([{
            id:0,
            title: '리액트 공부하기',
            body: '리액트 기초를 공부한다',
            isDone: false,
            doneButton: '완료'
        }]);
    
    return (
        <div className="layout">
            <Form />
            <Header setContents={setContents} contents={contents} />
            <List setContents={setContents}  contents={contents} />
         </div>
  • 데이터를 쌓기 위해서는 contents를 불러오고 새로운 데이터를 붙여준다 (push대신)
  • setContents로 변화를 넘겨준다
  • state의 변화
여기는 <Header>컴포넌트(하위)

const addContent = () => {
        let data = {
            id: props.contents.length,
            ...inputs,
            isDone: false,
            doneButton: '완료'
        }
        props.setContents([...props.contents, data])
        
    }

onChange 함수

  • React에서 onChange 이벤트는 사용자의 입력이 어떤 식으로든 변경될 때 발생, 사용자가 추가 텍스트를 입력하거나, 다른 옵션을 선택하거나, 확인란을 선택 취소하거나, 기타 유사한 경우에 입력이 변경될 수 있음
  • 여기서는 input의 value와 name을 비구조화 할당 (구조분해) 문법을 사용하여 const { name, value } = e.target; 객체 안에 있는 값을 추출해서 변수 혹은 상수로 바로 선언
  • 여러개의 inputs 값을 받으려면 setInputs안에 ...inputs(스프레드)를 써야 누적이 된다. (안써주면 새로운 값으로 덮어지기만 함)
const Header = (props) => {
    const [inputs, setInputs] = useState();
    
    const onChange = (e) => {
        const { name, value } = e.target;
        setInputs({
            ...inputs,
            [name]: value,
        })
    }

    return (
        <div className="headers">
            <div className="inputs">
                <div className="inputs-title">
                    <p>제목</p>
                    <input onChange={onChange} name='title' type='text'  ></input>
                </div>
                <div className="inputs-content">
                    <p>내용</p>
                    <input onChange={onChange} name='body' type='text' ></input>
                </div>
            </div>
        </div>
    )
}

filter, map함수

  • filter함수로 아이디가 같이 않은 것들을 골라서 setContents로 보내준다(그래야 리렌더링)
  const deleted = () => {
    // 1.  기존에 container 복사본에서 현재 지우고자 하는 content의 id와 같지 않은 데이터만 filter로 반환
      const newContents = [...container].filter((newCon) => newCon.id !== mapContent.id);
      
    // 2. 새로 만든 배열을 setContent로 업데이트
    setContents(newContents);
  };

map함수

  • 조건들을 넣어 새로운 배열로 담아준다
    const finished = () => {
      const changeIsDone = [...container].map((newState) => {
          //버튼이 취소일 때 
        if (newState.id === mapContent.id && newState.doneButton === '취소') {
          newState.isDone = false;
          newState.doneButton = '완료';
          return newState
        } 
        //완료버튼을 누를때
        if (newState.id === mapContent.id) {
          newState.isDone = true;
          newState.doneButton = '취소';
          return newState
        } else {return newState}
        })
        setContents(changeIsDone);
    }

배열과 유사 배열

  • Array.isArray 메서드(배열인지를 판단해주는 메서드)

  • 배열과 유사배열을 구분해야 하는 이유는, 유사배열의 경우 배열의 메서드를 쓸 수 없기 때문

  • array는 배열, nodes는 유사배열
    - els에 forEach같은 배열 메서드를 사용하면 에러가 발생,
    - nodes는 프로토타입에 forEach가 있어서 됨
    - 열이 아니므로 발생하는 것.
    - 이럴 때 메서드를 빌려 쓰는 방법이 있음. 배열 프로토타입에서 forEach 메서드를 빌려오는 것. 바로 call이나 apply


    - 이제 유사배열에도 forEach를 사용할 수 있음,
    map이나 filter, reduce 등의 다른 배열 메서드도 사용 가능

  • Array.from() 메소드를 통해 유사 배열 객체나 반복 가능한 객체를 얕게 복사해서 새로운 Array 객체를 만듦

  • 출처 : https://www.zerocho.com/category/JavaScript/post/5af6f9e707d77a001bb579d2


profile
winwin
post-custom-banner

0개의 댓글