컨테이너 구성 요소에서 프레젠테이션 구성 요소를 분리하려고합니다. 나는 SitesTable및 SitesTableContainer. 컨테이너는 현재 사용자를 기반으로 적절한 사이트를 가져 오기 위해 redux 작업을 트리거하는 역할을합니다.
문제는 컨테이너 구성 요소가 처음에 렌더링 된 후 현재 사용자를 비동기 적으로 가져 오는 것입니다. 이 수단은 컨테이너 구성 요소는 자신의 코드를 다시 실행해야 함을 알고하지 않는 componentDidMount받는 보낼 데이터를 업데이트 할 기능을 SitesTable. props (user) 중 하나가 변경되면 컨테이너 구성 요소를 다시 렌더링해야한다고 생각합니다. 이 작업을 올바르게 수행하려면 어떻게합니까?
class SitesTableContainer extends React.Component {
    static get propTypes() {
      return {
        sites: React.PropTypes.object,
        user: React.PropTypes.object,
        isManager: React.PropTypes.boolean
      }
     }
    componentDidMount() {
      if (this.props.isManager) {
        this.props.dispatch(actions.fetchAllSites())
      } else {
        const currentUserId = this.props.user.get('id')
        this.props.dispatch(actions.fetchUsersSites(currentUserId))
      }
    }
    render() {
      return <SitesTable sites={this.props.sites}/>
    }
}
function mapStateToProps(state) {
  const user = userUtils.getCurrentUser(state)
  return {
    sites: state.get('sites'),
    user,
    isManager: userUtils.isManager(user)
  }
}
export default connect(mapStateToProps)(SitesTableContainer);
답변
componentDidUpdate방법에 조건을 추가해야 합니다.
예제는 fast-deep-equal객체를 비교하는 데 사용됩니다.
import equal from 'fast-deep-equal'
...
constructor(){
  this.updateUser = this.updateUser.bind(this);
}
componentDidMount() {
  this.updateUser();
}
componentDidUpdate(prevProps) {
  if(!equal(this.props.user, prevProps.user)) // Check if it's a new user, you can also use some unique property, like the ID  (this.props.user.id !== prevProps.user.id)
  {
    this.updateUser();
  }
}
updateUser() {
  if (this.props.isManager) {
    this.props.dispatch(actions.fetchAllSites())
  } else {
    const currentUserId = this.props.user.get('id')
    this.props.dispatch(actions.fetchUsersSites(currentUserId))
  }
}
후크 사용 (React 16.8.0+)
import React, { useEffect } from 'react';
const SitesTableContainer = ({
  user,
  isManager,
  dispatch,
  sites,
}) => {
  useEffect(() => {
    if(isManager) {
      dispatch(actions.fetchAllSites())
    } else {
      const currentUserId = user.get('id')
      dispatch(actions.fetchUsersSites(currentUserId))
    }
  }, [user]);
  return (
    return <SitesTable sites={sites}/>
  )
}
비교하려는 소품이 객체 또는 배열 인 경우 useDeepCompareEffect대신을 사용해야 합니다 useEffect.
답변
ComponentWillReceiveProps()버그와 불일치로 인해 향후 지원이 중단 될 예정입니다. 소품 변화 요소를 재 렌더링을위한 대안 용액을 사용하는 것 ComponentDidUpdate()및 ShouldComponentUpdate().
ComponentDidUpdate()구성 요소가 업데이트 될 때마다 호출되고 ShouldComponentUpdate()true를 반환하면 ( ShouldComponentUpdate()정의되지 않은 경우 true기본적으로 반환 됨)
shouldComponentUpdate(nextProps){
    return nextProps.changedProp !== this.state.changedProp;
}
componentDidUpdate(props){
    // Desired operations: ex setting state
}
이 동일한 동작은 ComponentDidUpdate()내부에 조건문을 포함하여 메서드 만 사용하여 수행 할 수 있습니다 .
componentDidUpdate(prevProps){
    if(prevProps.changedProp !== this.props.changedProp){
        this.setState({
            changedProp: this.props.changedProp
        });
    }
}
조건부없이 또는 ShouldComponentUpdate()구성 요소 를 정의하지 않고 상태를 설정하려고 하면 무한히 다시 렌더링됩니다.
답변
KEY소품으로 변경되는 고유 키 (데이터 조합)를 사용할 수 있으며 해당 구성 요소는 업데이트 된 소품으로 다시 렌더링됩니다.
답변
componentWillReceiveProps(nextProps) { // your code here}
나는 그것이 당신이 필요한 이벤트라고 생각합니다. componentWillReceiveProps컴포넌트가 소품을 통해 무언가를받을 때마다 트리거됩니다. 거기에서 당신은 당신이 원하는 것을 할 수 있습니다.
답변
이 답변을 보는 것이 좋습니다. 을 그것이 당신이하는 일과 관련이 있는지 확인하는 것이 좋습니다. 실제 문제를 이해한다면 비동기 작업을 올바르게 사용하지 않고 redux “store”를 업데이트하면 자동으로 구성 요소가 새로운 소품으로 업데이트됩니다.
이 코드 섹션 :
componentDidMount() {
      if (this.props.isManager) {
        this.props.dispatch(actions.fetchAllSites())
      } else {
        const currentUserId = this.props.user.get('id')
        this.props.dispatch(actions.fetchUsersSites(currentUserId))
      }
    }
구성 요소에서 트리거하지 않아야하며 첫 번째 요청을 실행 한 후에 처리해야합니다.
redux-thunk 에서이 예제를 살펴보십시오 .
function makeASandwichWithSecretSauce(forPerson) {
  // Invert control!
  // Return a function that accepts `dispatch` so we can dispatch later.
  // Thunk middleware knows how to turn thunk async actions into actions.
  return function (dispatch) {
    return fetchSecretSauce().then(
      sauce => dispatch(makeASandwich(forPerson, sauce)),
      error => dispatch(apologize('The Sandwich Shop', forPerson, error))
    );
  };
}
반드시 redux-thunk를 사용할 필요는 없지만 이와 같은 시나리오를 추론하고 일치하는 코드를 작성하는 데 도움이됩니다.
답변
사용하기 쉬운 방법은 다음과 같습니다. prop이 업데이트되면 자동으로 컴포넌트를 다시 렌더링합니다.
render {
let textWhenComponentUpdate = this.props.text
return (
<View>
  <Text>{textWhenComponentUpdate}</Text>
</View>
)
}
답변
