[reactjs] redux 연결 구성 요소는 언제 다시 렌더링할지 어떻게 알 수 있습니까?
나는 아마도 매우 명백한 것을 놓치고 있고 스스로를 정리하고 싶습니다.
여기 내 이해가 있습니다.
순진한 반응 구성 요소에는 states
& props
. 로 업데이트 하면 전체 구성 요소 state
가 setState
다시 렌더링됩니다. props
대부분 읽기 전용이며 업데이트하는 것은 의미가 없습니다.
redux 저장소를 구독하는 반응 구성 요소에서, 같은 것을 통해 store.subscribe(render)
저장소가 업데이트 될 때마다 분명히 다시 렌더링됩니다.
반응-REDUX는 도우미를 가지고 connect()
그 같이 actionCreators (구성 요소에 대한 관심의) 상태 트리를 분사 부분 props
일반적으로 같은 것을 통해 구성 요소에
const TodoListComponent = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
그러나이 것을 이해 setState
(가)를 위해 필수적이다 TodoListComponent
REDUX 상태 트리 변경 (재 렌더링)에 반응하는, 나는 어떤 찾을 수 없습니다 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는 최적화 작업을 보여주지는 않지만 기본적인 아이디어를 보여주는 connect
at ( connect.js ) 의 매우 단순화 된 버전을 작성했습니다 . 또한 몇 가지 관련 아이디어를 논의 하는 Redux 성능 에 대한 여러 기사에 대한 링크가 있습니다 .
최신 정보
React-Redux v6.0.0 은 연결된 구성 요소가 저장소에서 데이터를받는 방식에 몇 가지 주요 내부 변경 사항을 적용했습니다.
그 일환으로 connect
API와 내부 기능이 작동하는 방식과 시간이 지남에 따라 어떻게 변했는지 설명하는 게시물을 작성했습니다 .
관용적 Redux : React-Redux의 역사와 구현
답변
내 대답은 약간 왼쪽 필드에서 벗어났습니다. 저를이 게시물로 이끈 문제에 대해 밝힙니다. 제 경우에는 새로운 소품을 받았음에도 불구하고 앱이 다시 렌더링되지 않는 것처럼 보였습니다.
React 개발자는이 자주 묻는 질문에 대해 (스토어)가 변형 된 경우 99 %의 시간이 반응이 다시 렌더링되지 않는 이유에 대한 답변을 받았습니다. 그러나 다른 1 %에 대해서는 아무것도 없습니다. 여기서 돌연변이는 그렇지 않았습니다.
TLDR;
componentWillReceiveProps
는state
새로운props
.
엣지 케이스 : 일단 state
업데이트, 다음 응용 프로그램이 않습니다 다시 렌더링!
앱이 state
요소를 표시 하는 데만 사용하는 경우 props
업데이트 할 수 있지만 업데이트 할 수 state
없으므로 다시 렌더링 할 수 없습니다.
나는 redux state
에서 props
받은 것에 의존했다 store
. 필요한 데이터가 아직 스토어에 없으므로에서 가져 왔습니다 componentDidMount
. 내 구성 요소가 mapStateToProps를 통해 연결되어 있기 때문에 감속기가 저장소를 업데이트했을 때 소품을 다시 얻었습니다. 그러나 페이지는 렌더링되지 않았고 상태는 여전히 빈 문자열로 가득 차있었습니다.
예를 들어 사용자가 저장된 URL에서 “게시물 편집”페이지를로드했다고 가정합니다. postId
URL에서에 액세스 할 수 있지만 정보가 store
아직 입력되지 않았으므로 가져옵니다. 페이지의 항목은 제어 된 구성 요소이므로 표시하는 모든 데이터는에 state
있습니다.
redux를 사용하여 데이터를 가져오고 저장하고 구성 요소를 connect
편집했지만 앱에 변경 사항이 반영되지 않았습니다. 자세히 살펴보면 props
수신되었지만 앱이 업데이트되지 않았습니다. state
업데이트하지 않았습니다.
글쎄, props
업데이트 및 전파되지만 state
그렇지 않습니다. state
업데이트 를 구체적으로 알려야 합니다.
이에 할 수 없어 render()
, 그리고 componentDidMount
이미의 사이클을 완료했다.
componentWillReceiveProps
state
변경된 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,
})
}
}
수십 개의 다른 게시물, 블로그 및 리포지토리에서 언급하지 않은 솔루션에 대해 깨달은이 기사에 한마디 부탁드립니다. 이 모호한 문제에 대한 답을 찾는 데 어려움을 겪은 다른 사람은 다음과 같습니다.
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}))