부모 컴포넌트의 상태 변경을 통한 고객 정보 갱신

Tin9oo·2023년 12월 9일
0

지난 게시물에서 새로운 항목 추가 시 전체 페이지를 갱신했다. 이는 single page application인 react에 효율적이지 않은 방식이다.

따라서, 부모 컴포넌트의 상태를 갱신하여 필요한 부분만 갱신하도록 설정해야한다.

부모에서 자식으로 함수를 props로 건네면 된다.

고객 불러와서 갱신

App.js에서 customer state 초기화 부분 삭제

const [customers, setCustomers] = useState('');
const [completed, setCompleted] = useState(0);

const callApi = async () => {
  const response = await fetch('/api/customers');
  const body = await response.json();
  return body;
};

const stateRefresh = () => {
  setCustomers('');
  setCompleted(0);
  this.callApi()
    .then(res => setCustomers(res))
    .catch(err => console.log(err));
};

useEffect(() => {
  const timer = setInterval(() => {
    setCompleted((prevCompleted) => (prevCompleted >= 100 ? 0 : prevCompleted + 10));
  }, 800);

  callApi()
    .then(res => setCustomers(res))
    .catch(err => console.log(err));

  return () => {
    clearInterval(timer);
  };
}, []);

Props를 넘기는데 함수를 넘긴다.

이제 CustomerAdd에서 항목이 추가되면 stateRefresh()가 실행되도록 하면 된다.

우선, 함수를 넘긴다.

<CustomerAdd stateRefresh={stateRefresh}/>

이때, this 없이 그냥 넘긴다.(함수형 컴포넌트에서 정의한 함수이기 때문이다.)

CustomerAdd.js의 window.location.reload()를 제거하고 this.props.stateRefres()를 추가한다.
하지만, 비동기적인 동작이라 고객 추가 후 정보를 불러오는 것을 순서적으로 보장하지 못한다.
고객을 추가하고 이후 서버로부터 응답을 받고 고객 목록을 다시 불러오도록 설정할 필요가 있다.

이를 보장하기 위해 다음과 같이 수정한다.

handleFormSubmit = (e) => {
  e.preventDefault();
  this.addCustomer()
    .then((response) => {
    console.log(response.data);
    this.props.stateRefresh();
  })
  this.setState({
    file: null,
    userName: '',
    birthday: '',
    gender: '',
    job: '',
    fileName: ''
  })
}

이제 항목을 추가해보면 고객 목록 부분만 갱신되는 것을 볼 수 있다.

구현 방식의 문제점

이런 구현방식도 문제가 있는데 갱신되는 컴포넌트의 수가 많아지는 경우 리소스가 비효율적으로 사용된다. 그래서 실제로는 상위 10개만 띄우고 스크롤을 통해 나머지가 출력되게 한다.

오류 발생

로딩이 안되는 오류가 발생했다.
callApi를 사용 후에 정의해서 문제가 발생함 순서를 조정하여 해결.
다른 해결방법으로 callApi를 stateRefresh()에서 부를 때 this.callApi를 사용했었는데 함수형이니까 this를 제거하니 정의하기 전에도 정상 로딩되는 것을 확인했다.

profile
🚙 HMG SOFTEER 3rd | 💻 BE

0개의 댓글