2024-03-21 70일차 React

민짱·2024년 3월 21일

📅2024. 03. 21 70일차


리스트 출력하는 다른 방식

기록 배열을 뒤집을 때는 .reverse 사용

ex)

{recordNums.reverse().map(recordNum => <li>{recordNum}</li>)}

전개구문으로 바꿀려면???

{[...recordNums].reverse().map(recordNum => <li>{recordNum}</li>)}

기록이 많아지면 어떤게 몇번째인지 모른다. 그때 사용가능한 것이 index
ex)

{recordNums.reverse().map(recordNum, index) => <li key={index}>{index + 1}: {recordNum}</li>)}

리액트(React), 리스트 출력하는 다른 방식

인덱스 filtering

//원본 배열
console.log("==원본==");
const arr = [10, 20, 30, 40, 50];
console.log(arr);

console.log("==filter 적용==");
const afterFilter = arr.filter((el, index) => index != 2);

console.log(afterFilter);
  • index !=2 가 참인 것은 배열에 저장하고 index 2인 30은 거짓이라 30을 빼고 [10,20,40,50]이 남는다.

  • const afterFilter = arr.filter((el, index) => index != 2); 에서 index만 쓸거면 const afterFilter = arr.filter((_, index) => index != 2);로 쓰는게 관례이다.

  • filter을 써도 arr는 불변성이다. 다시 arr를 찍어보면 그대로 들어가있다. 불변성을 지켜줘야 한다.

다른 방법

//원본 배열
console.log("==원본==");
const arr = [10, 20, 30, 40, 50];
console.log(arr);

console.log("==filter 적용==");
//const afterFilter = arr.filter((el, index) => index != 2);

const afterFilter = arr.filter((el, index) => {return el != 40;});

console.log(afterFilter);

filter을 이용한 삭제 (전체기록삭제, 해당 인덱스 삭제)

전체 삭제 clearNumbers 생성 setRecordNums을 초기화시키면 된다.

const clearNumbers = () => {
    setRecordNums([]);
  }; 

<button onClick={clearNumbers}>전체기록삭제</button>

해당 index 삭제

const removeNumber = (index) => {
    setRecordNums(recordNums.filter((_,_index) => _index != index));
  };

//생략
	<>
      <h5>기록</h5>
      <ul>
        {recordNums.map((recordNum, index) => (
        	<li key={index}>
              <span>
                {index + 1}: {recordNum}
              </span>
              &nbsp;
              <button onClick={() => removeNumber(index)}>삭제</button>
            </li>
           ))}
       </ul>
    </>

버튼을 각 index에 추가 인자값으로 index 넘겨주고 removerNumber에서 index값 받아 해당 자신의 index을 만났을 때 거짓으로 삭제

리액트(React), 아이템 삭제(filter)

함수 실행 방식의 차이

 <button onClick={saveNumber}>기록</button>

이것도 되고

 <button onClick={() => saveNumber()}>기록</button>

이것도 가능

함수 실행 방식

function a(index){
  console.log(`a 실행 됨, index : ${index}`);
}

// function b(){
//   a();
// }

// const b = function(){
//   a();
// }

const index = 2;

const b = () => { a(index) };
const c= a;

b();
c();

컴포던트 단위로 나누기

  • 블럭처럼 만들고 레고처럼 조립~
//생략~~
const NumberRecorderForm = ({ num, setNum, saveNumber, clearNumbers }) => {
  return (
    <>
      <div>
        <span>숫자 : {num}</span>
        &nbsp;
        <button onClick={() => setNum(0)}>취소</button>
      </div>
      <div>
        <button onClick={() => setNum(num + 1)}>증가</button>
        &nbsp;
        <button onClick={() => setNum(num - 1)}>감소</button>
        &nbsp;
        <button onClick={saveNumber}>기록</button>
        &nbsp;
        <button onClick={clearNumbers}>전체기록삭제</button>
      </div>
    </>
  );
};

const NumberRecorderList = ({ recordNums, removeNumber }) => {
  return (
    <>
      <div>
        {recordNums.length == 0 ? (
          <span>기록 없음</span>
        ) : (
          <>
            <h5>기록</h5>
            <ul>
              {recordNums.map((recordNum, index) => (
                <li key={index}>
                  <span>
                    {index + 1}: {recordNum}
                  </span>
                  &nbsp;
                  <button onClick={() => removeNumber(index)}>삭제</button>
                </li>
              ))}
            </ul>
          </>
        )}
      </div>
    </>
  );
};

const App = () => {
 
  //생략

  return (
    <>
      <NumberRecorderForm
        num={num}
        setNum={setNum}
        saveNumber={saveNumber}
        clearNumbers={clearNumbers}
      />
      <NumberRecorderList recordNums={recordNums} removeNumber={removeNumber} />
    </>
  );
};
  • NumberRecorderForm, NumberRecorderList을 따로 컴포던트화 시키고 따로 분리(블럭처럼 만들고~)
  • App에는 밑에처럼 조립하면 끝~~
 return (
    <>
      <NumberRecorderForm
        num={num}
        setNum={setNum}
        saveNumber={saveNumber}
        clearNumbers={clearNumbers}
      />
      <NumberRecorderList recordNums={recordNums} removeNumber={removeNumber} />
    </>
  );

리액트(React), 레코드 폼과 레코드 리스트로 컴포넌트 분리


템플릿 리터럴(Template literals)

  • 템플릿 리터럴은 내장된 표현식을 허용하는 문자열 리터럴이다.
  • 템플릿 리터럴은 표현식/문자열 삽입, 여러 줄 문자열, 문자열 형식화, 문자열 태깅 등 다양한 기능을 제공한다.

템플릿 리터럴 참고

토글 화면전환 (수정, 수정취소)

const ArticleDetail = ({ id }) => {
	const [editModeStatus, setEditModeStatus] = useState(false);

	const title = "1번 글 제목";
	const body = "1번 글 내용";

	if (editModeStatus) {
		return (
			<>
				<form>
					<div>수정모드</div>
					<span>번호</span>
					&nbsp;
					<span>{id}</span>
					<div>
						<span>제목</span>
						&nbsp;
						<input type="text" placeholder="제목을 입력해" />
					</div>
					<div>
						<span>내용</span>
						&nbsp;
						<input type="text" placeholder="내용을 입력해" />
					</div>
					<div>
						&nbsp;
						<button type="button">수정완료</button>
						&nbsp;
						<button type="button" onClick={() => {setEditModeStatus(false)}}>취소</button>
					</div>
				</form>
			</>
		);
	}

	return (
		<>
			<h3>{id}번 게시글</h3>
			<div>제목 : {title}</div>
			<div>내용 : {body}</div>
			<button onClick={() => {setEditModeStatus(true)}}>수정</button>
			&nbsp;
			<hr />
		</>
	);
};

const App = () => {
	return (
		<>
			<ArticleDetail />
		</>
	);
};
  • 수정을 누르면 setEditModeStatus가 true로 수정 폼 나오게 된다.

  • 수정 취소를 누르면 setEditModeStatus가 다시 false로 원래 나오는 detail로 돌아간다.

  • const [editModeStatus, setEditModeStatus] = useState(false); 만들어 참, 거짓으로 컨트롤 한다.

  • ArticleDetail을 따로 컴포던트화 시켜 조각으로 만들고 App에 조각을 끼워맞춘다. (이게 React의 장점인듯)

리액트(React), article detail 일반모드와 수정모드 토글

  • 수정모드를 NumberRecorderListItem에 적용 UI만

리액트(React), NumberRecorderListItem 수정모드 UI


수정버튼 눌렀을 때 value가 바뀌게 오류 수정

//생략
const NumberRecorderListItem = ({ index, number, removeNumber }) => {
  const [editModeStatus, setEditModeStatus] = useState(false);

  const readView = (
    <>
      <button onClick={() => setEditModeStatus(true)}>수정</button>
    </>
  );

  const editView = (
    <>
      <input
        type="number"
        placeholder="숫자 써"
        min="0"
        value={number}
        
      />
      &nbsp;
      <button onClick={() => setEditModeStatus(false)}>수정완료</button>
      &nbsp;
      <button onClick={() => setEditModeStatus(false)}>수정취소</button>
    </>
  );

기존에 벨류값을 number로 적용해서 값을 수정할 수 가 읍다...

  • const [inputNumberValue, setInputNumberValue] = useState(number); 추가하고 onChange 줘서 수정값 바뀌게 하면 된다.
const NumberRecorderListItem = ({ index, number, removeNumber }) => {
  const [inputNumberValue, setInputNumberValue] = useState(number);
  const [editModeStatus, setEditModeStatus] = useState(false);

  const readView = (
    <>
      <button onClick={() => setEditModeStatus(true)}>수정</button>
    </>
  );

  const editView = (
    <>
      <input
        type="number"
        placeholder="숫자 써"
        min="0"
        value={inputNumberValue}
        onChange={(e) => setInputNumberValue(e.target.value)}
      />
      &nbsp;
      <button onClick={() => setEditModeStatus(false)}>수정완료</button>
      &nbsp;
      <button onClick={() => setEditModeStatus(false)}>수정취소</button>
    </>
  );

리액트(React), NumberRecorderListItem 수정모드 input 태그의 값 변경 허용

  • 오늘의 나에게
    React 재밌게 잘 하자~

0개의 댓글