programing

프로펠러 변경 시 Re-render React 구성 요소

lastmemo 2023. 3. 7. 21:02
반응형

프로펠러 변경 시 Re-render React 구성 요소

컨테이너 컴포넌트에서 프레젠테이션 컴포넌트를 분리하려고 합니다.나는 가지고 있다SitesTable및 aSitesTableContainer컨테이너는 현재 사용자를 기반으로 적절한 사이트를 가져오는 redux 액션을 트리거하는 역할을 합니다.

문제는 컨테이너 컴포넌트가 처음 렌더링된 후 현재 사용자가 비동기적으로 Import된다는 것입니다.즉, 컨테이너 컴포넌트는 컨테이너 컴포넌트에서 코드를 재실행할 필요가 있음을 인식하지 못합니다.componentDidMount에 송신할 데이터를 갱신하는 기능SitesTable소품(사용자)이 바뀌면 컨테이너 컴포넌트를 다시 렌더해야 할 것 같습니다.어떻게 하면 좋을까요?

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방법.

이 예에서는 을 사용하여 개체를 비교하고 있습니다.

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}/>
  )

}

비교하는 프로펠러가 오브젝트 또는 어레이인 경우 대신 을 사용해야 합니다.

componentWillReceiveProps()버그나 불일치로 인해 향후 폐지될 예정입니다.소품 교환 시 컴포넌트를 재렌더하기 위한 대체 솔루션은componentDidUpdate()그리고.shouldComponentUpdate().

componentDidUpdate()컴포넌트가 갱신될 때마다 호출됩니다.shouldComponentUpdate()true를 반환한다(IfshouldComponentUpdate()정의되어 있지 않다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를 사용할 필요는 없지만, 이와 같은 시나리오를 추론하고 그에 맞는 코드를 작성하는 데 도움이 됩니다.

사용하기 쉬운 방법은 다음과 같습니다. 프로펠러가 업데이트되면 컴포넌트가 자동으로 다시 렌더링됩니다.

render {

let textWhenComponentUpdate = this.props.text 

return (
<View>
  <Text>{textWhenComponentUpdate}</Text>
</View>
)

}

해서 '아까불까불까불까불까불까불까불까불까불까불까불까불까불까불까불까요?getDerivedStateFromProps()라고 하는,의 라이프 메서드를 합니다.props이치노상태를 업데이트하면 렌더가 다시 생성됩니다.뭇매를 맞다

static getDerivedStateFromProps(nextProps, prevState) {
  return { myStateProperty: nextProps.myProp};
}

'보다 낫다'의 됩니다.myStateProperty, 「Component」의 이 .myProp이치노

이 방법을 사용할 경우 발생할 수 있는 잠재적인 영향을 이해해야 합니다. 아니게 .props부모 컴포넌트에서 예기치 않게 갱신되었습니다.에 따라 됨)를 할 수 .prevState의 착신 )에 「」를 참조해 주세요.props값을 지정합니다.

하는 것은, 「업데이트하다」의 이 「업데이트 한다」의 입니다.props상태 값의 진실의 원천입니다.만약 그렇다면, 여러분이 필요로 하는 것을 성취할 수 있는 더 간단한 방법이 있을 수도 있습니다.참고 항목 - 파생 상태가 필요하지 않을 있습니다리액트 블로그

언급URL : https://stackoverflow.com/questions/37009328/re-render-react-component-when-prop-changes

반응형