TIL (Today I learn)

10월 20일 (화)_Final Project - 03 (state 비동기 처리)

청조인 2020. 10. 20. 22:40

오늘의 프로젝트 진행 상황

1. state 비동기 처리

2. 해결 - 서버의 데이터 흐름 변경

1. state 비동기 처리

  Test 등록 버튼을 눌렀을 때 선택된 단어가 바로 등록이되고 화면이 재렌더링 되면서 해당 단어가 보이지 않게 되어야했습니다. 그런데 예상과는 달리 화면상에 그대로 나타나있는 상태로 렌더링이 되었습니다. 이 상태에서 다시 한번 Test 등록 버튼을 누르면 선택된 단어가 그제서야 안보이게 되었습니다. 저희는 이 문제를 state의 비동기처리에 의한 문제로 파악하였고 관련 자료들을 검색하는 도중에 해결 방안을 찾아 내었습니다.

2. 해결 - 서버의 데이터 흐름 변경

  조사 결과 클라이언트 측에서도 문제가 있었지만 그 문제는 asnyc/await 를 활용하여 해결을 하였고 정작 더 중요했던 문제는 서버측 코드에서 데이터 처리가 완료된 이후 응답을 보내야하지만 그렇지 않고 데이터 처리 도중에 클라이언트측에 응답을 보냈던게 문제였습니다. 아래는 해결한 코드입니다.

1. 클라이언트 측 코드

// 랜더링시 데이터를 받아옴
  componentDidMount() {
    this.props.navigation.addListener('focus', () => {
      this.fetchData();
    });
  }

  // Data를 받아오기 위해 서버에 요청하는 곳
  //데이터를 받아올 때 상태값으로 isSelect과 selectedClass 를 넣어줌
  //isSelect 은 item의 선택여부, selectedClass는 그에 따른 스타일 변경
  async fetchData() {
    this.setState({ loading: true }, function () {
      console.log('this.state : ', this.state);
    });
    let userId = await AsyncStorage.getItem('userId');

    try {
      const response = await fetch(`${Address}/word/mine/${userId}`);
      const responseJson = await response.json();

      responseJson.map((item) => {
        console.log('item : ', item);
        item.isSelect = false;
        item.selectedClass = styles.list;
        return item;
      });
      this.setState({
        loading: false,
        dataSource: responseJson,
      });
    } catch (e) {
      console.error(e);
      this.setState({ loading: false });
    }
  }

2. Server측 코드

const { mineWord } = require("../../models");
const { Op } = require("sequelize");
module.exports = {
  post: (req, res) => {
    // let { userid } = req.session;
    // console.log("userid", req.session.userid);
    // var tDate = new Date("2022-07-10 12:30");
    let { selectedWords, id } = req.body;
    let selectWord_EngList = selectedWords.map((el) => {
      return el.word_eng;
    });
    console.log("selectWordList -> ", selectWord_EngList);
    if (Array.isArray(selectedWords)) {
      mineWord
        .update(
          {
            distinguish: 0,
            check_in: new Date(),
            check_out: new Date(),
          },
          {
            where: {
              user_id: id,
              distinguish: 99,
              word_eng: {
                [Op.in]: selectWord_EngList,
              },
            },
          }
        )
        .then((data) => {
          res.status(200).json(data);
        })
        .catch((e) => {
          res.sendStatus(500);
        });
    }
  },
};

  보시면 then() 이후 res.status(200)을 보내는 형식입니다. 하지만 이전에는 then을 통하지 않고 데이터 변경과 res.status(200)이 따로 동작이 되고 있었습니다. 결국 이 두가지를 다써서 지금은 Test 등록 버튼을 누를 시에 바로바로 데이터가 변경되고 적용이 되는 형식으로 만들었습니다. 오늘의 프로젝트 진행을 통해 state 비동기 처리에 대해 정말 많은 것을 배웠고 백 엔드 측에서도 데이터를 어떻게 처리해야 더 올바른 흐름인지를 많이 배웠습니다.