REACT

[React] 인프런 스터디

Hanee_ 2021. 11. 28. 00:06

누구든지 하는 리액트 강좌

https://www.inflearn.com/course/react-velopert/dashboard

 

누구든지 하는 리액트: 초심자를 위한 react 핵심 강좌 - 인프런 | 강의

프론트엔드 프레임워크, 리액트(React)를 누구든지 쉽고 재밌게 시작할 수 있도록 만들어진 강의입니다., 누구나 쉽개 배우는 리액트React!리액트의 기초를 튼튼하게 다져보세요. 핵심을 잡아주는

www.inflearn.com

 

Constructer

자바스크립트에서 super 는 부모클래스 생성자의 참조이다. 그리고 자바스크립트는 언어적 제약사항으로서 생성자에서 super 를 호출하기 전에는 this 를 사용할 수 없다. 생성자 내부에서도 this.props 를 정상적으로 사용할 수 있도록 보장한다.

...
class Counter extends Component{
	state={number:0}
    
    constructor(props){
    	//can't use 'this'
    	super(props);
        //can use 'this'
        this.handleIncrease=this.handleIncrease.bind(this);
    }
    
    handleIncrease(){
    	console.log(this);
        this.setState({
        	number:this.state.number+1
        })
    }
    
    ...
}

 

React Life Cycle

constructor : 컴포넌트가 가진 state 초기 설정

 

배열에 데이터 삽입하기

//1. concat, ...
handleCreate=(data)=>{
	const {information} =this.state;
    this.setState({
    	information:information.concat({
        	...data,
            id:this.id++
        })
    })
}

//2. concat
handleCreate=(data)=>{
	const {information} =this.state;
    this.setState({
    	information:information.concat({
        	name=data.name,
            phone=data.phone,
            id:this.id++
        })
    })
}

//3. Object.assign
handleCreate=(data)=>{
	const {information} =this.state;
    this.setState({
    	information:information.concat(Object.assign({},data, {
            id:this.id++
        })
    })
}

 

 

App.js

import "./styles.css";
import React, { Component } from "react";
import PhoneForm from './component/PhoneForm'
import PhoneInfoList from "./component/PhoneInfoList";
class App extends Component{

  id=0;
  
  state={
    information:[]
  }
  
  handleCreate=(data)=>{
    const {information}=this.state;
    this.setState({
      information:information.concat({
        ...data,
        id:this.id++
 	})})}


//e : 이벤트 객체
//input 값이 바뀔 때마다 값이 바뀜
  handleChange=(e)=>{
    this.setState({
      keyword:e.target.value
   })}


//요소 제거
  handleRemove=(id)=>{
    const {information}=this.state;
    this.setState({
      information : information.filter(info=>info.id!==id)
    })}
    
//요소 수정
  handleUpdate=(id, data)=>{
    const {information} = this.state;
    this.setState({
      information:information.map(
        info => {
          if (info.id===id){
            return{
              id,
              ...data,
            }}
          return info;
     })})}

  render(){
    return(
      <div>
        <PhoneForm onCreate={this.handleCreate}/>
        <input 
          value={this.state.keyword}
          onChange={this.handleChange}
          placeholder="검색... "
        />
        <PhoneInfoList 
          data={this.state.information.filter(
            info=>info.name.indexOf(this.state.keyword)>-1
          )}
          onRemove={this.handleRemove}
          onUpdate={this.handleUpdate}
          />
      </div>
    )
  }
}
export default App;

 

component/PhoneInfo.js

import React, {Component,Fragment} from 'react';

class PhoneInfo extends Component{

  state={
    editing: false,
    name:'',
    phone:''
  }
  handleRemove=()=>{
    const {info, onRemove}=this.props;
    onRemove(info.id)
  }
  handleToggleEdit=()=>{
    //true->false : onUpdate
    //false->true : state에 info 값 넣어줌
    const {info, onUpdate}=this.props;
    if(this.state.editing){
      onUpdate(info.id,{
        name:this.state.name,
        phone:this.state.phone
      });
    } else{
      this.setState({
        name:info.name,
        phone:info.phone
      }) }
    this.setState({
      editing: !this.state.editing,
    })}
  handleChange=(e)=>{
    this.setState({
      [e.target.name]:e.target.value
    })}

  render(){
    const {name,phone}=this.props.info;
    const {editing} = this.state;

    const style={
      border:'1px solid black',
      padding : '8px',
      margin:'8px'
    }

    return(
      <div style={style}>
        {
          editing?(
            <Fragment>
              <div>
              <input 
                name="name" value={this.state.name} onChange={this.handleChange}
              /></div>
              <div><input onChange={this.handleChange} name="phone" value={this.state.phone}
              /></div>
            </Fragment>
          ):(
            <Fragment>
              <div><b>{name}</b></div>
              <div><b>{phone}</b></div>
            </Fragment>
          )
        }
        <button onClick={this.handleRemove}>삭제</button>
        <button onClick={this.handleToggleEdit}>{
          editing ? '적용' : '수정'
        }</button>
      </div>
 )    }}
export default PhoneInfo;

 

component/PhoneInfoList.js

import React,{Component} from 'react';
import PhoneInfo from './PhoneInfo';

class PhoneInfoList extends Component{

//값이 null일때 오류 생성 방지
  static defaultProps={
    data:[]
  }

  render(){
    const { data, onRemove, onUpdate }=this.props;
    const list=data.map(
      info=>(
        <PhoneInfo 
         onUpdate={onUpdate}
          onRemove={onRemove} 
          info={info} 
          key={info.id}/>)
    )
    return(
      <div>
        {list}
      </div>
    )
  }
}
export default PhoneInfoList;

 

component/PhoneForm.js

import React,{Component} from 'react';

class PhoneForm extends Component{

  input = null;

  handleSubmit=(e)=>{
    e.preventDefault();
    this.props.onCreate(this.state);
    this.setState({
      name:'',
      phone:''
    })
    this.input.focus();
    //this.input.current.focus()
  }

  state={
    name:'',
    phone:''
  }

  handleChange=(e)=>{
    this.setState({
      [e.target.name]:e.target.value
    })
  }

  render(){
    return(
        <form onSubmit={this.handleSubmit}>
          <input 
            name="name"
            placeholder="이름" 
            onChange={this.handleChange} 
            value={this.state.name}
            ref={ref=>this.input=ref}
            />
          <input 
            name="phone"
            placeholder="전화번호" 
            onChange={this.handleChange} 
            value={this.state.phone}/>
          <button type="submit">등록</button>
        </form>
 )}}
export default PhoneForm