2024-03-25 71일차 React

민짱·2024년 3월 26일

📅2024. 03. 25 71일차


문제

  • NumberRecordListItem 분리 및 수정버튼 추가 기능 x

NumberRecorderList를 NumberRecordListItem으로 분리 시도

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>
		</>
	);
};

위에서 기록부분의 ul를 Item으로 분리 후 수정 버튼 추가 수정 누르면 다시 일반모드로 변경

const NumberRecorderList = ({ recordNums, removeNumber }) => {
	return (
		<>
			<div>
				{recordNums.length == 0 ? (
					<span>기록 없음</span>
				) : (
					<>
						<h5>기록</h5>
						<ul>
							{recordNums.map((number, index) => (
								<NumberRecorderListItem
									key={index}
									number={number}
									index={index}
									removeNumber={removeNumber}
								/>
							))}
						</ul>
					</>
				)}
			</div>
		</>
	);
};

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>
		</>
	);

	return (
		<>
			<li>
				<span>
					{index + 1}: {number}
				</span>
				&nbsp;
				<button onClick={() => removeNumber(index)}>삭제</button>
				&nbsp;
				{editModeStatus ? editView : readView}
			</li>
		</>
	);
};
  • 수정완료 기능구현 (React. codepen)

현재 수정완료 버튼을 눌러도 그 값으로 수정되지 않는다.

const NumberRecorderListItem = ({
	index,
	number,
	recordNums,
	setRecordNums,
	removeNumber }) => {
	const [inputNumberValue, setInputNumberValue] = useState(number);
	const [editModeStatus, setEditModeStatus] = useState(false);

	const modifyNumber = () => {
		if (number == inputNumberValue) return;
		
		
		setRecordNums(recordNums.map((_number,_index) => _index == index ? inputNumberValue : _number));
		setEditModeStatus(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={modifyNumber}>수정 완료</button>
			&nbsp;
			<button onClick={() => setEditModeStatus(false)}>수정 취소</button>
		</>
	);

	return (
		<>
			<li>
				<span>
					{index + 1}: {number}
				</span>
				&nbsp;
				<button onClick={() => removeNumber(index)}>삭제</button>
				&nbsp;
				{editModeStatus ? editView : readView}
			</li>
		</>
	);
};
<NumberRecorderList 				
	recordNums={recordNums}
	setRecordNums={setRecordNums}
	removeNumber={removeNumber} />
		</>

modifyNumber 컴포턴트화 NumberRecorderListItem에 recordNums, setRecordNums 추가 recordNums 값을 가져와서 수정하게

App의 NumberRecorderList에 setRecordNums 추가

  • if (number == inputNumberValue) return; 만약 가져온 값이랑 인풋값이랑 같으면 리턴시켜버리게 조건걸기

  • setRecordNums(recordNums.map((_number,_index) => _index == index ? inputNumberValue : _number));
    배열을 돌려서 현재 인덱스 값이랑 같으면 인풋값으로 수정 다르면 원래값 유지

코드펜

문제점 발생 수정을 음수로 못하게 막기, 수정 취소시 input 값을 초기화 시키기

  • 수정값을 음수로 수정 못 하게 구현

어떻게??? 조건문 사용? 만약에 인풋값이 0보다 작으면 리턴시켜???
if (inputNumberValue < 0) return; 이렇게?? 코드적용 결과 음수 넣으면 수정안되게는 막음 근데 먼가 비효율적 음수 넣으면 그냥 현재값으로 바꾸게 할까??

그럼 조건문으로 만약 인풋값이 0보다 작으면 setInputNumberValue을 현재값으로 넣고 setEditModeStatus을 false로 바꾸면 다시 일반모드로 전환 해결완료!!!!

  • 해결완료
		if (inputNumberValue < 0) {
			setInputNumberValue(number);
			setEditModeStatus(false);
			return;
		}

이렇게 하면 음수 넣었을 때, setInputNumberValue을 현재 number값으로 유지하고 setEditModeStatus을 false로 바뀌게 해서 일반모드로 전환

  • 수정 취소시 입력한 인풋값이 유지되는게 아니라 초기화 시키기

일단 수정 부분으로 가서 코드 분석해야할듯??

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

이 부분에서 값을 차지하는 value={inputNumberValue} 코드에서 문제가 발생하는 듯??
벨류값을 인풋값으로 넣어놨으니까 수정취소하고 다시 수정 눌러도 전에 넣어놨던 인풋값이 그대로 있는 듯
이거 삭제해도 되지 않을까???

  • value={inputNumberValue} 삭제하니까 수정취소하고 다시 수정 눌러도 전에 입력한 값 안남게된다.

해결완료!!!!!!!!!

문제해결완료

React Style 방법

<!-- 테일윈드 불러오기 -->
<script src="https://cdn.tailwindcss.com"></script>

tailwind cheat sheet
daisyui

<방법 1>

<div
	style={{ width: "100px", height: "100px", backgroundColor: "red" }}
></div>

<방법 2>

const style1 = {
		width: "100px",
		height: "100px",
		backgroundColor: "gold"
	};

//생략
<div style={style1}></div>

<방법 3>

/* 라이브러리 클래스 */
.square {
	width: 100px;
	height: 100px;
	background-color: blue;
}

//생략
<div className="square"></div>

<방법 4>

<div className="w-[100px] h-[100px] bg-[#8ceda6]"></div>

<방법 5>

<input type="text" placeholder="Type here" className="input input-bordered input-info w-full max-w-xs" />

<방법 6>

<div className="overflow-x-auto">

리액트(React), tailwind, daisyUI 문제

똑같이 구현하기

console.clear();

import React, { useState } from "https://cdn.skypack.dev/react@18";
import ReactDOM from "https://cdn.skypack.dev/react-dom@18";

const IncreNumber = ({ num, setNum}) => {
  return (
    <>
      <div style={{textAlign:"center"}}>
        <input
        type="number"
        value={num}
        min="1"
		className="input input-bordered w-full max-w-xs"
      />
	  <button style={{marginLeft:"1%"}}className="btn btn-active btn-primary" onClick={() => setNum(num + 1)}>증가</button>
      </div>
    </>
  );
};

const App = () => {
	const [num, setNum] = useState(1);
	return (
		<>
			<IncreNumber
				num={num}
        		setNum={setNum}
				/>
		</>
	);
};

ReactDOM.render(<App />, document.getElementById("root"));

문제점 발생

  • 증가버튼 누르면 숫자가 증가하긴 하는데 input에 있는 화살표 누르면 증가가 안된다...

  • 해결방법 : 따로 컨포던트화 시켜서 onClick줘야 할 듯?

const IncreNumber = ({ num, setNum}) => {
	  const handleInputChange = (event) => {
    	const newValue = parseInt(event.target.value);
    setNum(newValue);
  };

handleInputChange 속성 만들기

      <div style={{textAlign:"center"}}>
        <input
        type="number"
        value={num}
        min="1"
		className="input input-bordered w-full max-w-xs"
		onChange={handleInputChange}
      />

인풋에 onChange={handleInputChange} 추가하여 문제해결 완료.

슨생님.var

console.clear();

import React, { useState } from "https://cdn.skypack.dev/react@18";
import ReactDOM from "https://cdn.skypack.dev/react-dom@18";

const App = () => {
	const [num, setNum] = useState(0);

	return (
		<>
			<div className="h-full flex items-center justify-center gap-x-[10px]">
				<form className="flex gap-x-[10px]" onSubmit={(e) => e.preventDefault()}>
					<input
						value={num}
						className="input input-bordered"
						type="number"
						placeholder="숫자 입력"
						onChange={(e) => setNum(e.target.valueAsNumber)}
						min="1"
					/>
					<button type="submit" className="btn btn-primary" onClick={() => setNum(num + 1)}>
						증가
					</button>
				</form>
			</div>
		</>
	);
};

ReactDOM.render(<App />, document.getElementById("root"));

TODOLIST(React)

console.clear();

import React, { useState } from "https://cdn.skypack.dev/react@18";
import ReactDOM from "https://cdn.skypack.dev/react-dom@18";

const App = () => {
	const [todos, setTodos] = useState([])

// 	setTimeout(function(){
// 		setTodos([...todos, todos.length + 1]);	
// 	},5000);
	
	return (
		<>
			<div></div>
			<hr/>
			<div>
				{JSON.stringify(todos)}
			</div>
		</>
	);
};

ReactDOM.render(<App />, document.getElementById("root"));
  • 5초마다 재 랜더링 ~ useState 특성 확인

TODO 추가 폼

console.clear();

import React, { useState } from "https://cdn.skypack.dev/react@18";
import ReactDOM from "https://cdn.skypack.dev/react-dom@18";

const App = () => {
	const [todos, setTodos] = useState([]);
	const [newTodoTitle, setNewTodoTitle] = useState("");
	
	const addTodo = () => {
		setTodos([...todos,newTodoTitle]);
	}
	
	return (
		<>
			<div className="flex gap-x-3">
				<input
					className="input input-bordered"
					type="text"
					placeholder="할 일 적어"
					value={newTodoTitle}
					onChange={(e) => setNewTodoTitle(e.target.value)}
				/>
				<button className="btn btn-primary" onClick={addTodo}>
					할 일 추가
				</button>
			</div>
			<hr />
			<div>{JSON.stringify(todos)}</div>
		</>
	);
};

ReactDOM.render(<App />, document.getElementById("root"));
  • 인풋 입력 값 그냥 배열에 추가만 되게 구현

띄어쓰기 안먹게 구현

const addTodo = () => {
		const trimmedTitle  = newTodoTitle.trim();
		if(trimmedTitle.length == 0) return;
  • 조건 추가

0개의 댓글