• 카테고리

    질문 & 답변
  • 세부 분야

    프론트엔드

  • 해결 여부

    미해결

20.3 update에서 state변경이 안되는지 변경이 안됩니다

24.04.07 21:21 작성 조회수 58

1

app.js

import './App.css';
import { Component } from 'react';
import TOC from "./Components/TOC";
import ReadContent from "./Components/ReadContent";
import CreateContent from "./Components/CreateContent";
import UpdateContent from "./Components/UpdateContent";
import Subject from "./Components/Subject";
import Control from "./Components/Control";


class App extends Component {
  constructor(props){
    super(props);
    this.max_content_id = 3;
    this.state = {
      mode: 'create',
      selected_content_id: 2,
      Subject: {title: "WEB", sub: "world wide web~~ hyun"},
      welcome: {title: "Welcome", desc: "Hello, React~~"},
      contents: [
        {id:1, title:'HTML', desc:'HTML is for information'},
        {id:2, title:'CSS', desc:'CSS is for Design'},
        {id:3, title:'JavaScript', desc:'JavaScript is for interactive'}
      ]
    }
  }
  getReadContent() {
    var i = 0;
    while(i < this.state.contents.length){
        var data = this.state.contents[i];
        if(data.id === this.state.selected_content_id){
          return data;
          break;
        }
      i = i + 1;
    }  
  }
  getContent(){   
    var _title, _desc, _article = null;
    if(this.state.mode === 'welcome'){
      _title = this.state.welcome.title; 
      _desc = this.state.welcome.desc;
      _article = <ReadContent title={_title} desc={_desc}></ReadContent>
    }else if(this.state.mode === 'read'){
      var _content = this.getReadContent();
      _article = <ReadContent title={_content.title} desc={_content.desc}></ReadContent>    
    }else if(this.state.mode === 'create') {
      _article = <CreateContent onSubmit = {function(_title, _desc){
          // add content to this.state.contents
          this.max_content_id = this.max_content_id + 1;
         // this.state.contents.push (    
         //   {id:this.max_content_id, title:_title, desc:_desc}
         // );
         var _contents = this.state.contents.concat(
          {id:this.max_content_id, title:_title, desc:_desc}
          )
         // var newContents = Array.from(this.state.contents);
         // newContents.push({id:this.max_content_id, 
         //   title:_title, desc:_desc});
            this.setState ({
              //contents:this.state.contents
              contents: _contents
            });          
          console.log(_title, _desc);
      }.bind(this)}></CreateContent>
    } else if(this.state.mode === 'update') {
      _content = this.getReadContent();
      _article = <UpdateContent data={_content} onSubmit = {
        function(_id, _title, _desc){
          // add content to this.state.contents
  // 14 line에 this.max_content_id = 3; 는 create에 사용된 것이므로 아래내용주석처리
         // this.max_content_id = this.max_content_id + 1;
         //복제기능 수행 : 원본을 복사한 새로운 배열 생성
         var _contents = Array.from(this.state.contents);
         //수정하고자하는 원소값과 같은 것을 찾는다.
            var i = 0;
            while(i < _contents.length){
              //_contents[i].id갑과 입력한 id값이 같다면
              if(_contents[i].id === _id){
                _contents[i] = {id:_id, title:_title, desc:_desc};
                break;                
              }
              i = i + 1;
            }
            this.setState ({
              //contents:this.state.contents
              //contents: newContents
              contents:_contents
            });          
          console.log(_id, _title, _desc);
      }.bind(this)}></UpdateContent>
    }
    return _article;
  }
  render() {
    console.log('App render');

  return (
    <div className="App">
      <Subject 
        title= {this.state.Subject.title} 
        sub= {this.state.Subject.sub}
          onChangePage = { function () {
          this.setState({ mode:'welcome'});
        }.bind(this)}
        >
      </Subject> 

      <TOC 
         onChangePage = { function (id) {
          this.setState({ 
            mode:'read',
            selected_content_id:Number(id) 
          });
         
        }.bind(this)}             
      
      data={this.state.contents}></TOC>
      <Control onChangeMode={function(_mode) {
        this.setState ({
          mode:_mode
        });
    }.bind(this)}></Control>
      {this.getContent()}  
    </div>
  );
}
}
export default App;

UpdateContent.js

import { Component } from 'react';

class UpdateContent extends Component {
  constructor(props){
    super(props);
    this.state = {
      id:this.props.id,
      title:this.props.data.title,
      desc:this.props.data.desc
    }
    this.inputFormHandler = this.inputFormHandler.bind(this);
  }
  inputFormHandler(e) {
    this.setState({[e.target.name]:e.target.value});   

  }
    render() {
      //this.props.title = 'hi;
      console.log(this.props.data);
      console.log('UpdateContent render');
      return (
        <article>
              <h2>Update</h2>
            <form action='/create_process' method='post' 
              onSubmit={function(e){
                e.preventDefault();
                this.props.onSubmit(  // state의 동기화 
                  this.state.id,
                  //e.target.title.value, // _title
                  this.state.title,
                  //e.target.desc.value   // _desc
                  this.state.desc
                );
            }.bind(this)}
            >
              <input type="hidden" name="id" value={this.state.id}></input>
              <p>
                <input type="text" 
                  name="title" 
                  placeholder='title'
                  value={this.state.title}
                  //onChange = {this.inputFormHandler.bind(this)}
                  onChange = {this.inputFormHandler}
                  ></input>
              </p>
              <p>
                <textarea 
               // onChange = {this.inputFormHandler.bind(this)}
               onChange = {this.inputFormHandler}
                name="desc" 
                placeholder='description' value={this.state.desc}></textarea>
              </p>
              <p>
                <input type="submit" ></input>
              </p>
            </form>
          </article>
      );
    }
  }

  export default UpdateContent;
  

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.04.08

안녕하세요, 인프런 AI 인턴입니다.

삼계해마님의 질문에 대한 답변입니다. State 변경이 안되는 문제를 진단하기 위해 제시하신 코드를 살펴보았습니다. UpdateContent.js에서 상태(state)를 초기화할 때, id 값을 설정하는 과정에서 문제가 발견됩니다.

초기 state 설정 부분에서 id의 값을 this.props.id로 설정하려고 시도하고 있으나, 실제로 App.js에서 UpdateContent 컴포넌트에 id를 직접적으로 props로 전달하지 않고 있습니다. 대신 data 객체 안에 id가 포함되어 있기 때문에, 초기 state를 설정할 때 다음과 같이 수정해야 합니다.

this.state = {
  id: this.props.data.id, // 수정된 부분
  title: this.props.data.title,
  desc: this.props.data.desc
}

위와 같이 변경함으로써, UpdateContent 컴포넌트의 초기 상태가 부모 컴포넌트로부터 제대로 전달받은 props를 반영하여 설정됩니다. 따라서 state와 props 사이에서의 데이터 불일치 문제가 해결될 수 있습니다.

또한, 상태 업데이트는 비동기적으로 이루어지므로, 상태 변경 후 즉시 변경된 상태를 기대하고 로직을 작성하는 것은 주의가 필요합니다. 상태 업데이트 후 변경된 상태에 기반한 작업이 필요하다면, 상태 업데이트 함수(setState)의 콜백 함수를 사용하는 것이 좋습니다.

잘 해결되길 바랍니다. 추가적인 질문이 있으시면 언제든지 문의해주세요.