submitLoginInfo
send보다 submit을 사용하면 폼에 있는 데이터를 백엔드 서버로 보낸다는 의미를 더 함축적으로 전달할 수 있다.
LoginInfo : 어떤 정보를 보내는지를 포함할 수 있다.
const regex = new RegExp('@');
const validId = regex.exec(emailInputVal);
if (validId && pwInputVal.length >= 5) {
setValidState(true);
} else {
setValidState(false);
}
const emailValidatorReg = new RegExp('@');
const validId = emailValidatorReg.exec(emailInputVal);
if (validId && pwInputVal.length >= 5) {
setValidState(true);
} else {
setValidState(false);
}
if (validId && pwInputVal.length >= 5) {
setValidState(true);
} else {
setValidState(false);
}
const isFormValid = validId && pwInputVal.length >= 5;
setValidState(isFormValid);
emailValidatorReg = new RegExp();
const isFormValid = validId && pwInputVal.length >=5;
setValidstate(isFormValid)
function handleInput(e) {
const {name, vlaue} = e.target;
className={`button ${isActive ? '' : 'inactive'}`}
disabled = {!isValid}
feeds && feeds[0].map
function handleuserInput(event){
const {name, value} = event.target;
setUserInput({...userInput, [name]: value});
}
[name]을 해주는 이유는, 고정값이 아닌 바뀌는 값이기 때문에 계산된 속성명을 사용하는 것이다.
function addComment(e) {
e.preventDefault();
let updated = comments;
const newCommentVal = commentRef.current.value;
updated = [
...updated,
{ id: uuid(), commentId: myId, commentText: newCommentVal },
];
setComments(updated);
commentRef.current.value = '';
}
function addComment(e) {
e.preventDefault();
const newComment = {
id: uuid(),
commentId: myId,
commentText: newCommentVal,
};
const newCommentVal = commentRef.current.value;
setComments([...comments, newComment]);
commentRef.current.value = '';
}
function deleteComment(comment) {
const updated = comments;
const filtered = updated.filter(com => {
return com.id !== comment.id;
});
setComments(filtered);
}
function deleteComment(comment) {
const filteredComments = comments.filter(com => {
return com.id !== comment.id;
});
setComments(filteredComments);
}
function handleTextContent(text) {
if (text.length > 30) {
text = text.slice(0, 30);
return (
<>
<p>{text}</p>
<button className="more-text">...더보기</button>
</>
);
} else {
return text;
}
}
<div className="textContent">{handleTextContent(feed.textContent)}</div>
function showMore(text) {
return (
<>
<p>{text.slice(0, 30)}</p>
<button className="more-text">...더보기</button>
</>
);
}
<div className="textContent">
{feed.textContent.length > 30
? showMore(feed.textContent)
: feed.textContent}
</div>
다른 state를 가지고 계산 가능한 것은 state가 아니다.
const [isActive, setIsActive] = useState(false)
//다른 state나 props를 가지고 계산되는 것은 state로 쓸 필요 없다.
//불필요하게 복잡해지기 때문이다.
//이미 state가 있기 때문에, 다음과 같이 그저 변수로만 계산한 값을 할당해 만들어주면 된다.
const isActive = id.includes('@') && password.length > 4;
Feed({feedData}) {
const [comments, setComments] = useState([...feedData.commentList]);
//state가 각각 따로 놀게 되는 위험이 있다.
//전달받은 props를 그대로 수정해주는 것이 좋다.
const handleFeedComment = (feedId, comment) => {
setFeeds(prevFeeds => {
return prevFeeds.map(prevFeed => {
if(prevFeed.id === feed.id) {
return {...prevFeed, comment: comment};
}
return prevFeed;
});
});
setFeeds(nextFeeds)
}
ref는 값을 수정해도 렌더링을 하지 않음
ref는 하나로 사용해 객체형태로 사용해도 좋다.
굳이 렌더링을 하지 않아도 될 때는 ref값을 사용하는 것이 좋다.
<button
disabled={validState ? false : true}
<button
disabled={!validState}
function MainGayun() {
const [stories, setStories] = useState();
async function loadStories() {
const data = await (
await fetch('http://localhost:3000/data/Gayun/story.json')
).json();
setStories(data);
}
useEffect(() => {
loadStories();
}, []);
return (
<div className="main-gayun">
<Nav />
<Story stories={stories} />
<div className="main-content">
<Feeds />
{stories && <SideBar stories={stories} />}
Sidebar가 꼭 데이터가 들어온 뒤 나중에 보여야 하는게 아니라면, SideBar 내부에서 처리를 해주는 것이 더 적절하다.
그러나 state 초기값을 빈 배열로 준다면 이것 또한 필요없다.
초기값이 빈배열이므로 빈 상태로 스토리의 내부를 채우고, 이후에 state 업데이트 되어 값이 채워졌을 때 리렌더링 되어 스토리 안의 컨텐츠가 다시 표시되기 때문이다.
고유값을 만들어주는 라이브러리를 사용했는데, 이것은 렌더링 시마다 각기 다른 값을 생성하기 때문에 불필요하다.
map의 두번째 인자로 index를 키값으로 주는 방법도 생각해봤는데, 이 방법 또한 인덱스를 키 값으로 주는 것이기 때문에 삭제및 추가의 상황에서 적절하지 않다.
데이터 내부에 아이디로 지정할만한 값이 포함되어 있지 않을 때 사용할 최선의 방법이 있을 것이라고 생각했는데, 데이터에서 고유한 값을 아이디로 지정하는 것이 가장 좋은 선택지였다.