이번에는 form 형태로 된 습관을 입력할 수 있는 input을 만들어본다.
우선 habitaddform.jsx를 만든다.
form 형식이니까 div로 감싸주지말고, form으로 감싸준다.
render() {
return (
<form className="add-form">
<input
type="text"
className="add-input"
placeholder="Habit"
/>
<button className="add-button">Add</button>
</form>
);
}
이렇게 form 태그 안에 input과 button을 만들어서 form 형식을 만들어준다.
그 후 form은 onSubmit 으로 버튼을 클릭했을 때 보내질 수 있도록 만들어져야 하므로 form에 onSubmit 함수를 추가한다.
onSubmit = (event) => {
event.preventDefault();
};
render() {
return (
<form className="add-form" onSubmit={this.onSubmit}>
<input
type="text"
className="add-input"
placeholder="Habit"
/>
<button className="add-button">Add</button>
</form>
);
}
event 함수를 받고, event.preventDefault(); 로 form이 submit 되어도 새로고침 되지 않게 막아준다.
리액트는 dom과 다르게 input 안의 value를 받아오려면, ref를 사용해야 한다.
class HabitAddForm extends Component {
formRef = React.createRef();
inputRef = React.createRef();
onSubmit = (event) => {
event.preventDefault();
const name = this.inputRef.current.value;
name && this.props.onAdd(name);
// this.inputRef.current.value = "";
this.formRef.current.reset();
};
render() {
return (
<form ref={this.formRef} className="add-form" onSubmit={this.onSubmit}>
<input
ref={this.inputRef}
type="text"
className="add-input"
placeholder="Habit"
/>
<button className="add-button">Add</button>
</form>
);
}
}
리액트에서 제공하는 ref를 사용해서 this.inputRef.current.value로 input 에 있는 값을 받아온다. input 태그 안에 ref를 선언해서 this.inputRef 해주면 된다.
이 habitaddform.jsx 는 app이 아닌 habits에서 참조받아서 사용한다.
그러므로 habits에서 props를 부여한다.
일단 habits.jsx 에서 render 할 때, habitaddform도 import 해서 return 해준다.
habits.jsx
handleAdd = (name) => {
this.props.onAdd(name);
};
render() {
return (
<>
<HabitAddForm onAdd={this.handleAdd} />
<ul>
{this.props.habits.map((habit) => (
<Habit
key={habit.id}
habit={habit}
onIncrement={this.handleIncrement}
onDecrement={this.handleDecrement}
onDelete={this.handleDelete}
/>
))}
</ul>
</>
);
}
이렇게 habitaddform에 onadd를 props로 받고, this.handleadd 를 작성해준다.
이 handleadd는 props로 넘겨받는 것이 좋다. 다른 increment나 decrement 같이 props로 넘겨받도록 함수를 선언해주고, 대신 습관의 name을 적는 것이니까 Habit이 아닌 name으로 인자값을 넣어준다.
app.jsx
handleAdd = (name) => {
const habits = [
...this.state.habits,
{ id: Date.now(), name: name, count: 0 },
];
this.setState({ habits });
};
render() {
return (
<>
<Navbar
totalCount={this.state.habits.filter((item) => item.count > 0).length}
/>
<Habits
habits={this.state.habits}
onIncrement={this.handleIncrement}
onDecrement={this.handleDecrement}
onDelete={this.handleDelete}
onAdd={this.handleAdd}
/>
</>
);
}
app.jsx 에서 habits props로 onAdd를 받고
handleAdd 이벤트를 처리해준다. 여기서 처리해주어야 할 것은, state 안의 요소값을 하나 더 만드는 것이다.
그것은
const habits = [...this.state.habits] 로 일단 habits을 복사한 후, [...this.state.habits , {id: Date.now(), name: name, count: 0} ]
처럼 name만 인자값을 받을 수 있게 만들어주고 고유 키 값인 id는 중복되지 않게 지금 시간으로 넣어준다.
그 후 setState를 해주면 state 안에 값이 생성되어 들어가서 input 했을 때 똑같이 출력이 된다.
'React' 카테고리의 다른 글
react PureComponent 정리와 차이점 이해 (성능 분석) (0) | 2022.09.07 |
---|---|
react reset 버튼 만들기 (0) | 2022.09.07 |
react habit nav 컴포넌트 만들기 (0) | 2022.09.07 |
react 이벤트 처리하기 (0) | 2022.09.07 |
react Habits 컴포넌트 만들기 (state up, list key) (0) | 2022.09.06 |