[reactjs] redux 연결 구성 요소는 언제 다시 렌더링할지 어떻게 알 수 있습니까?

나는 아마도 매우 명백한 것을 놓치고 있고 스스로를 정리하고 싶습니다.

여기 내 이해가 있습니다.
순진한 반응 구성 요소에는 states& props. 로 업데이트 하면 전체 구성 요소 statesetState다시 렌더링됩니다. props대부분 읽기 전용이며 업데이트하는 것은 의미가 없습니다.

redux 저장소를 구독하는 반응 구성 요소에서, 같은 것을 통해 store.subscribe(render)저장소가 업데이트 될 때마다 분명히 다시 렌더링됩니다.

반응-REDUX는 도우미를 가지고 connect()그 같이 actionCreators (구성 요소에 대한 관심의) 상태 트리를 분사 부분 props일반적으로 같은 것을 통해 구성 요소에

const TodoListComponent = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

그러나이 것을 이해 setState(가)를 위해 필수적이다 TodoListComponentREDUX 상태 트리 변경 (재 렌더링)에 반응하는, 나는 어떤 찾을 수 없습니다 state또는 setState에서 관련 코드 TodoList구성 요소 파일을. 다음과 같이 읽습니다.

const TodoList = ({ todos, onTodoClick }) => (
  <ul>
    {todos.map(todo =>
      <Todo
        key={todo.id}
        {...todo}
        onClick={() => onTodoClick(todo.id)}
      />
    )}
  </ul>
)

누군가 내가 놓친 것에 대해 올바른 방향으로 나를 가리킬 수 있습니까?

추신 나는 redux 패키지 와 함께 번들로 제공되는 할 일 목록 예제를 따르고 있습니다.



답변

connect함수는 상점을 구독하는 랩퍼 구성 요소를 생성합니다. 작업이 전달되면 래퍼 구성 요소의 콜백에 알림이 전송됩니다. 그런 다음 mapState함수 를 실행 하고이 시간의 결과 객체와 지난 시간의 결과 객체를 얕게 비교 합니다 (따라서 동일한 값으로 redux 저장소 필드 를 다시 작성 하는 경우 다시 렌더링을 트리거하지 않습니다). 결과가 다르면 결과를 “실제”구성 요소 “에 소품으로 전달합니다.

Dan Abramov는 최적화 작업을 보여주지는 않지만 기본적인 아이디어를 보여주는 connectat ( connect.js ) 의 매우 단순화 된 버전을 작성했습니다 . 또한 몇 가지 관련 아이디어를 논의 하는 Redux 성능 에 대한 여러 기사에 대한 링크가 있습니다 .

최신 정보

React-Redux v6.0.0 은 연결된 구성 요소가 저장소에서 데이터를받는 방식에 몇 가지 주요 내부 변경 사항을 적용했습니다.

그 일환으로 connectAPI와 내부 기능이 작동하는 방식과 시간이 지남에 따라 어떻게 변했는지 설명하는 게시물을 작성했습니다 .

관용적 Redux : React-Redux의 역사와 구현


답변

내 대답은 약간 왼쪽 필드에서 벗어났습니다. 저를이 게시물로 이끈 문제에 대해 밝힙니다. 제 경우에는 새로운 소품을 받았음에도 불구하고 앱이 다시 렌더링되지 않는 것처럼 보였습니다.
React 개발자는이 자주 묻는 질문에 대해 (스토어)가 변형 된 경우 99 %의 시간이 반응이 다시 렌더링되지 않는 이유에 대한 답변을 받았습니다. 그러나 다른 1 %에 대해서는 아무것도 없습니다. 여기서 돌연변이는 그렇지 않았습니다.


TLDR;

componentWillReceivePropsstate새로운 props.

엣지 케이스 : 일단 state업데이트, 다음 응용 프로그램이 않습니다 다시 렌더링!


앱이 state요소를 표시 하는 데만 사용하는 경우 props업데이트 할 수 있지만 업데이트 할 수 state없으므로 다시 렌더링 할 수 없습니다.

나는 redux state에서 props받은 것에 의존했다 store. 필요한 데이터가 아직 스토어에 없으므로에서 가져 왔습니다 componentDidMount. 내 구성 요소가 mapStateToProps를 통해 연결되어 있기 때문에 감속기가 저장소를 업데이트했을 때 소품을 다시 얻었습니다. 그러나 페이지는 렌더링되지 않았고 상태는 여전히 빈 문자열로 가득 차있었습니다.

예를 들어 사용자가 저장된 URL에서 “게시물 편집”페이지를로드했다고 가정합니다. postIdURL에서에 액세스 할 수 있지만 정보가 store아직 입력되지 않았으므로 가져옵니다. 페이지의 항목은 제어 된 구성 요소이므로 표시하는 모든 데이터는에 state있습니다.

redux를 사용하여 데이터를 가져오고 저장하고 구성 요소를 connect편집했지만 앱에 변경 사항이 반영되지 않았습니다. 자세히 살펴보면 props수신되었지만 앱이 업데이트되지 않았습니다. state업데이트하지 않았습니다.

글쎄, props업데이트 및 전파되지만 state그렇지 않습니다. state업데이트 를 구체적으로 알려야 합니다.

이에 할 수 없어 render(), 그리고 componentDidMount이미의 사이클을 완료했다.

componentWillReceivePropsstate변경된 prop값 에 의존하는 속성을 업데이트하는 곳 입니다.

사용 예 :

componentWillReceiveProps(nextProps){
  if (this.props.post.category !== nextProps.post.category){
    this.setState({
      title: nextProps.post.title,
      body: nextProps.post.body,
      category: nextProps.post.category,
    })
  }
}

수십 개의 다른 게시물, 블로그 및 리포지토리에서 언급하지 않은 솔루션에 대해 깨달은이 기사에 한마디 부탁드립니다. 이 모호한 문제에 대한 답을 찾는 데 어려움을 겪은 다른 사람은 다음과 같습니다.

ReactJs 구성 요소 수명주기 방법 — 심층 분석

componentWillReceiveProps업데이트 state와 동기화를 유지하기 위해 업데이트 할 곳 props입니다.

일단 state업데이트, 다음 에 따라 필드 state DO 다시 렌더링!


답변

이 답변은 You Probably Do n’t Need Derived State (2018 년 6 월 7 일) 라는 제목의 Brian Vaughn의 기사 요약입니다 .

소품에서 상태를 가져 오는 것은 모든 형태의 반 패턴입니다. 이전 componentWillReceiveProps및 최신 getDerivedStateFromProps.

props에서 상태를 파생하는 대신 다음 솔루션을 고려하십시오.

두 가지 모범 사례 권장 사항

권장 사항 1. 완전히 제어되는 구성 요소

function EmailInput(props) {
  return <input onChange={props.onChange} value={props.email} />;
}

권장 사항 2. 키가있는 완전히 제어되지 않는 구성 요소

// parent class
class EmailInput extends Component {
  state = { email: this.props.defaultEmail };

  handleChange = event => {
    this.setState({ email: event.target.value });
  };

  render() {
    return <input onChange={this.handleChange} value={this.state.email} />;
  }
}

// child instance
<EmailInput
  defaultEmail={this.props.user.email}
  key={this.props.user.id}
/>

어떤 이유로 든 권장 사항이 상황에 맞지 않는 경우 두 가지 대안이 있습니다.

대안 1 : ID 소품으로 제어되지 않는 구성 요소 재설정

class EmailInput extends Component {
  state = {
    email: this.props.defaultEmail,
    prevPropsUserID: this.props.userID
  };

  static getDerivedStateFromProps(props, state) {
    // Any time the current user changes,
    // Reset any parts of state that are tied to that user.
    // In this simple example, that's just the email.
    if (props.userID !== state.prevPropsUserID) {
      return {
        prevPropsUserID: props.userID,
        email: props.defaultEmail
      };
    }
    return null;
  }

  // ...
}

대안 2 : 인스턴스 메서드를 사용하여 제어되지 않는 구성 요소 재설정

class EmailInput extends Component {
  state = {
    email: this.props.defaultEmail
  };

  resetEmailForNewUser(newEmail) {
    this.setState({ email: newEmail });
  }

  // ...
}


답변

내가 redux 가하는 일 만 알고 있기 때문에 구성 요소가 변경된 상태에 종속되어 있으면 componentWillRecieveProps를 호출하고 구성 요소를 강제로 업데이트해야합니다.

1-store State change-2-call (componentWillRecieveProps (() => {3-component state change}))


답변