상위 상태 변경 후 하위 구성 요소가 업데이트되지 않음
다양한 자 컴포넌트에 데이터를 채울 수 있는 멋진 ApiWrapper 컴포넌트를 만들려고 합니다.제가 읽은 바로는 이 방법이 효과가 있을 것 같습니다.https://jsfiddle.net/vinniejames/m1mesp6z/1/
class ApiWrapper extends React.Component {
constructor(props) {
super(props);
this.state = {
response: {
"title": 'nothing fetched yet'
}
};
}
componentDidMount() {
this._makeApiCall(this.props.endpoint);
}
_makeApiCall(endpoint) {
fetch(endpoint).then(function(response) {
this.setState({
response: response
});
}.bind(this))
}
render() {
return <Child data = {
this.state.response
}
/>;
}
}
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {
data: props.data
};
}
render() {
console.log(this.state.data, 'new data');
return ( < span > {
this.state.data.title
} < /span>);
};
}
var element = < ApiWrapper endpoint = "https://jsonplaceholder.typicode.com/posts/1" / > ;
ReactDOM.render(
element,
document.getElementById('container')
);
그러나 어떤 이유로 부모 상태가 변경되었을 때 자식 구성 요소가 업데이트되지 않는 것 같습니다.
내가 뭘 빠트렸나요?
코드에는 두 가지 문제가 있습니다.
자녀 구성요소의 초기 상태는 소품으로 설정됩니다.
this.state = {
data: props.data
};
이 SO 답변에서 인용:
를 컴포넌트로
prop
'이 되는 이유는 '이기 때문입니다.getInitialState
(이 경우 컨스트럭터) 메서드는 컴포넌트가 처음 렌더링될 때만 호출됩니다.더 이상은 안돼요.즉, 컴포넌트를 재렌더하여 다른 값을 전달하면prop
컴포넌트는 처음 렌더링되었을 때부터 상태를 유지하기 때문에 컴포넌트는 이에 따라 반응하지 않습니다.오류가 발생하기 쉽습니다.
그래서 그런 상황을 피할 수 없다면 새로운 소품을 듣는 방법을 사용하는 것이 가장 이상적인 해결책입니다.
하위 구성 요소에 다음 코드를 추가하면 하위 구성 요소 재렌더링 문제가 해결됩니다.
componentWillReceiveProps(nextProps) {
this.setState({ data: nextProps.data });
}
는 '''에 입니다.fetch
_makeApiCall(endpoint) {
fetch(endpoint)
.then((response) => response.json()) // ----> you missed this part
.then((response) => this.setState({ response }));
}
여기 작동 중인 바이올린이 있습니다. https://jsfiddle.net/o8b04mLy/
위의 해결 방법으로도 문제가 해결되지 않는 경우, 일단 상태를 변경하는 방법을 확인하고, 새로운 오브젝트를 반환하지 않는 경우, 때로는 새로운 이전과 변경된 상태의 차이가 보이지 않는 경우, 상태를 변경할 때 항상 새로운 오브젝트를 통과하는 것이 좋습니다.새로운 오브젝트가 확실하게 반응하는 것을 볼 수 있습니다.변경된 상태에 액세스할 수 있는 필요한 모든 컴포넌트를 다시 표시합니다.
예: -
여기서 내 상태의 개체 배열의 속성을 하나 변경합니다. 새 개체에서 모든 데이터를 어떻게 분산시키는지 살펴봅니다.또한 아래 코드는 다소 생소해 보일 수 있습니다.리덕스 리덕터 기능이지만, 상태를 변경하기 위한 수단일 뿐이므로 걱정하지 마십시오.
export const addItemToCart = (cartItems,cartItemToBeAdded) => {
return cartItems.map(item => {
if(item.id===existingItem.id){
++item.quantity;
}
// I can simply return item but instead I spread the item and return a new object
return {...item}
})
}
새 개체로 상태를 변경하는지 확인하십시오. 상태를 약간 변경하더라도 새 개체로 확장한 후 다시 돌아가면 모든 적절한 위치에서 렌더링이 트리거됩니다.도움이 됐으면 좋겠네요.틀린 곳이 있으면 알려주세요:)
당신이 바꿔야 할 것들이 있어요.
언제fetch
응답을 얻습니다. json이 아닙니다.어떻게 하면 이 json을 얻을 수 있을까 하다가 이 링크를 발견했습니다.
다른 한편으로, 당신은 생각할 필요가 있다.constructor
함수는 한 번만 호출됩니다.
따라서 데이터 취득 방법을 변경해야 합니다.<Child>
요소.
여기 코드 예를 남겼습니다.https://jsfiddle.net/emq1ztqj/
도움이 됐으면 좋겠어요.
수락된 답변 및componentWillReceiveProps
그componentWillReceiveProps
call in accepted answer는 권장되지 않으며 React with version 17 React Docs에서 삭제됩니다.
React에서 파생 상태 로직 사용
React 문서가 지적하고 있듯이 파생 상태(즉, 소품에서 발생한 변경을 반영하는 컴포넌트)를 사용하면 컴포넌트가 생각하기 어려워지고 안티패턴이 될 수 있습니다.React Docs: 파생 상태가 필요하지 않을 수 있습니다.
현재 솔루션:getDerivedStateFromProps
파생 상태를 사용하도록 선택한 경우 현재 솔루션은getDerivedStateFromProps
@Diogo Santo가 말한 대로 호출합니다.
초기 마운트 및 후속 업데이트 모두에서 렌더 메서드를 호출하기 직전에 GetDerivedStateFromProps가 호출됩니다.상태를 업데이트하려면 개체를 반환하고 업데이트하지 않으려면 null을 반환해야 합니다.리액트 문서:
사용방법componentWillReceiveProps
이 메서드는 인스턴스 속성에 액세스할 수 없습니다.주어진 소품에서 새로운 상태를 계산하는 방법을 React에 설명하는 모든 것입니다.소품이 변경될 때마다 React는 이 메서드를 호출하고 이 메서드에서 반환된 개체를 새 상태로 사용합니다.
class Child extends React.Component {
constructor() {
super(props);
// nothing changed, assign the state for the
// first time to teach its initial shape.
// (it will work without this, but will throw
// a warning)
this.state = {
data: props.data
};
}
componentWillReceiveProps(props) {
// return the new state as object, do not call .setState()
return {
data: props.data
};
}
render() {
// nothing changed, will be called after
// componentWillReceiveProps returned the new state,
// each time props are updated.
return (
<span>{this.state.data.title}</span>
);
}
}
주의.
- 부모 컴포넌트에서 발생한 변경에 따라 컴포넌트를 재렌더하면 해당 컴포넌트에 대한 사용자 입력이 손실되므로 사용자가 번거로워질 수 있습니다.
- 파생된 상태 논리는 컴포넌트를 이해하기 어렵게 만들 수 있습니다.현명하게 사용하세요.
언급URL : https://stackoverflow.com/questions/41233458/react-child-component-not-updating-after-parent-state-change
'programing' 카테고리의 다른 글
GSON이 인터페이스 타입에 대해 타입 어댑터를 호출하지 않음 (0) | 2023.03.04 |
---|---|
AngularJS - 컨트롤러에서 날짜 변환 (0) | 2023.03.04 |
Django에서 AJAX 게시 후 리다이렉트 (0) | 2023.03.04 |
중첩된 경로 angularjs를 사용할 때 "상태에서...를 해결할 수 없습니다" 오류가 표시됨 (0) | 2023.03.04 |
게시 후 폼 값을 유지하는 방법 (0) | 2023.03.04 |