React : 자식에서 부모의 state 변경

김영준·2020년 1월 12일
1

react

목록 보기
1/4
post-thumbnail

리액트에서 부모컴포넌트에서 자식 컴포넌트로 props를 넘겨주는 것은 매우 쉽다.
하지만 반대로 자식에서 부모의 컴포넌트의 state를 변경해줘야 하는 일이 필요하다.

어떻게 하면 바꿀 수 있을까 ??

바로 form 태그를 사용해서 바꿀 수 있다.
출처는 이곳이다. 이곳에 나와 있는 설명을 풀어보면 다음과 같다.

<부모컴포넌트>
import { Component } from 'react';

class App extends Component {

    onSearchSubmit(text) {
    	console.log(text);
    }

    render (
    	<div>
       		<Searchbar onSubmit={this.onSearchSubmit}/>
        </div>
    );

}
<자식컴포넌트>
import { Component } from 'react';

class Searchbar extends Component {

    state = { text: '' };

    onFormSubmit = e => {
    	e.preventDefault();
        this.props.onSubmit(this.state.text);
    }

    render (
    	<div>
            <form onSubmit={this.onFormSubmit}>
       			<input 
            		value={this.state.text}
            		onChange={(e) => {this.setState({ text: e.tartget.value})}}/>
            </form>
        </div>
    );

}

<정리>
1. 부모컴포넌트에서 자식 컴포넌트로 onSubmit이라는 이름으로 props를 넘겨준다.
2. 자식컴포넌트에서는 onSubmit이라는 props로 받아온 함수를 실행시킨다. 언제 실행시키느냐?
바로 <form>태그 에서 클릭했을 때(onSubmit을 할 때) 실행되는 함수(onFormSubmit)안에서 실행시킨다.
3. onFormSubmit을 보면 this.props.onSubmitstate에 있는 값을 넣어서 실행시킨다.
<Form> 태그는 부모로 값을 전달해주기 때문에 가능하다.


내가 사용한 방법을 설명해보면 다음과 같다.

<자식컴포넌트>
import React, { PureComponent } from "react";

import { Icon, Layout, Modal, Divider } from "antd";
import { deleteCookie } from "../../../framework/utils/CommonUtil";
import { TOKEN_NAME } from "../../../framework/utils/ApiUtil";

class Header extends PureComponent {
  _back = () => {
    const { current, history } = this.props;
    if (history.location.search === "") {
      if (current === 0 || current === 3) {
        history.push("/main");
      } else {
        this._onSubmit(current - 1); // _onSubmit 사용
      }
      if (!current) {
        history.push("/main");
      }
    } else if (history.location.search !== "") {
      history.push("/fitting/list");
    }
  };

  _onSubmit = e => {
    this.props.onSubmit(e);
  };

  render() {
    const { displayTitle, current } = this.props;
    return (
      <div>
        <Layout.Header className="header-section">
          <div className="header-back-arrow" onClick={this._back}>
            <form onSubmit={this._onSubmit}>
              <Icon type="left" />
            </form>
          </div>
        </Layout.Header>
        <Divider style={{ margin: 0 }} />
      </div>
    );
  }
}

export default Header;

눈여겨 봐야할 곳은 redner밑의 return부분에서 <div className="header-back-arrow" onClick={this._back}>부분이다.
_back함수가 실행된 부분을 보자. this._onSubmit이 사용되는데 _onSubmit을 보면 this.props.onSubmit(e)이 사용된다. props로 받아온 onSubmit함수에 (current-1)을 인자로 넘겨 주고 있다.

즉, 뒤로가기를 누르면 현재 current에서 -1을 한다는 것이다.

<부모컴포넌트>
class FitView extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      current: props.fitting
        ? this._stateCdType(props.fitting.content.fitStateCd)
        : 0,
    };
  }
  // props.num ? this._stateCdType(props.num) : 0

  _forHeader = num => {
    this.setState({ current: num });
  };

  render() {
    const { current, displayTitle1, displayTitle2 } = this.state;
    const { history } = this.props;

    return (
      <>
        {current === 3 ? (
          //current 3 은 step 0, 1, 2(신체정보,클럽정보,스윙정보)를 완료한 상태를 의미
          <>
            <Header
              history={history}
              displayTitle={displayTitle2}
              current={this.state.current}
              onSubmit={this._forHeader}
            />
            <FitResult {...this.state} fitting={this.props.fitting} />
          </>
        ) : (
          <>
            <Header
              history={history}
              displayTitle={displayTitle1}
              current={this.state.current}
              onSubmit={this._forHeader}
            />
          );
        }
      }	

export default FitView;

<Header>컴포넌트를 살펴보면 onSubmit={this._forHeader}가 있다. num 으로 넘어온 값에 따라서 this.setState를 하여 state에 있는current를 변경해 준다.

onSubmit이라는 이름으로 this._forHeader라는 함수를 내려주고, 자식 컴포넌트에서는 props로 내려온 onSubmit에 숫자를 넣어줘서 Submit 하게 되면 부모의 state가 바뀐다!!

처음 올리는 포스팅이라 정리가 안된다. 출처를 들어가면 깔끔하고 요점만 딱 정리되어 있으니 그것만 봐도 사용하는데 무리가 없을것이다.

다시한번 남기는 출처

profile
프론트엔드 개발자 김영준 입니다. 디테일함을 키우고 있습니다

0개의 댓글