[reactjs] 반응 양식의 소품 변경 상태 업데이트
React 양식에 문제가 있고 상태를 올바르게 관리하고 있습니다. 양식에 모달로 된 시간 입력 필드가 있습니다. 초기 값은의 상태 변수로 설정되며 getInitialState
상위 구성 요소에서 전달됩니다. 이것은 그 자체로 잘 작동합니다.
부모 구성 요소를 통해 기본 start_time 값을 업데이트하려고 할 때 문제가 발생합니다. 업데이트 자체는를 통해 상위 구성 요소에서 발생합니다 setState start_time: new_time
. 그러나 내 양식에서 기본 start_time 값은에 한 번만 정의되므로 변경되지 않습니다 getInitialState
.
를 componentWillUpdate
통해 상태를 강제로 변경 하려고 시도했지만 setState start_time: next_props.start_time
실제로 작동했지만 Uncaught RangeError: Maximum call stack size exceeded
오류가 발생했습니다.
내 질문은,이 경우 상태를 업데이트하는 올바른 방법은 무엇입니까? 어떻게 든이 잘못에 대해 생각하고 있습니까?
현재 코드 :
@ModalBody = React.createClass
getInitialState: ->
start_time: @props.start_time.format("HH:mm")
#works but takes long and causes:
#"Uncaught RangeError: Maximum call stack size exceeded"
componentWillUpdate: (next_props, next_state) ->
@setState(start_time: next_props.start_time.format("HH:mm"))
fieldChanged: (fieldName, event) ->
stateUpdate = {}
stateUpdate[fieldName] = event.target.value
@setState(stateUpdate)
render: ->
React.DOM.div
className: "modal-body"
React.DOM.form null,
React.createElement FormLabelInputField,
type: "time"
id: "start_time"
label_name: "Start Time"
value: @state.start_time
onChange: @fieldChanged.bind(null, "start_time”)
@FormLabelInputField = React.createClass
render: ->
React.DOM.div
className: "form-group"
React.DOM.label
htmlFor: @props.id
@props.label_name + ": "
React.DOM.input
className: "form-control"
type: @props.type
id: @props.id
value: @props.value
onChange: @props.onChange
답변
반응식 16 이후 componentWillReceiveProps는 depcricated입니다 . 대신 getDerivedStateFromProps 를 사용하십시오 .
올바르게 이해하면 상위 구성 요소로 전달되는 상위 구성 요소가 있습니다 start_time
.ModalBody
자신의 상태에 할당 구성 요소로 있습니까? 그리고 하위 구성 요소가 아닌 상위에서 해당 시간을 업데이트하려고합니다.
React에는이 시나리오를 다루는 데 유용한 정보가 있습니다. (이 기사는 웹에서 삭제 된 이전 기사입니다. 컴포넌트 props에 대한 현재 문서에 대한 링크가 있습니다.)
소품을 사용하여 상태를 생성하는 것은
getInitialState
종종 “진실의 근원”, 즉 실제 데이터가있는 곳의 복제로 이어집니다. 이 때문입니다getInitialState
구성 요소를 처음 작성할 때만 호출 입니다.가능할 때마다 값을 즉시 계산하여 나중에 동기화되지 않고 유지 보수 문제를 유발하지 않도록하십시오.
기본적으로 부모 props
를 자식 에게 할당 할 때마다 state
prop 업데이트시 render 메서드가 항상 호출되는 것은 아닙니다. componentWillReceiveProps
메소드를 사용하여 수동으로 호출해야합니다 .
componentWillReceiveProps(nextProps) {
// You don't have to do this check first, but it can help prevent an unneeded render
if (nextProps.startTime !== this.state.startTime) {
this.setState({ startTime: nextProps.startTime });
}
}
답변
분명히 상황이 바뀌고 있습니다 … getDerivedStateFromProps () 가 이제 선호되는 기능입니다.
class Component extends React.Component {
static getDerivedStateFromProps(props, current_state) {
if (current_state.value !== props.value) {
return {
value: props.value,
computed_prop: heavy_computation(props.value)
}
}
return null
}
}
답변
componentWillReceiveProps
“종종 버그와 불일치가 발생하기 때문에”더 이상 사용되지 않습니다.
외부에서 무언가가 바뀌면으로 하위 구성 요소를 완전히 재설정하는 것이key
좋습니다.
key
자식 구성 요소에 소품을 제공 key
하면 외부 의 값이 변경 될 때마다이 구성 요소가 다시 렌더링됩니다. 예 :
<EmailInput
defaultEmail={this.props.user.email}
key={this.props.user.id}
/>
성능상 :
느리게 들릴 수 있지만 일반적으로 성능 차이는 중요하지 않습니다. 하위 트리에 대해 diffing이 무시되므로 구성 요소에 업데이트시 실행되는 논리가 많은 경우 키를 사용하는 것이 더 빠를 수도 있습니다.
답변
도 있습니다 componentDidUpdate 이 없습니다.
기능 signatur :
componentDidUpdate(prevProps, prevState, snapshot)
컴포넌트가 업데이트 될 때 DOM에서 작동 할 수있는 기회로 이것을 사용하십시오. initial에 호출되지 않습니다 render
.
보기 당신은 아마 국가 파생하지 않아도 모두 안티 패턴을 설명 제, componentDidUpdate
와 getDerivedStateFromProps
. 나는 그것이 매우 유용하다는 것을 알았습니다.
답변
이 작업을 수행하는 새로운 후크 방법은 componentWillReceiveProps 대신 useEffect를 사용하는 것입니다.
componentWillReceiveProps(nextProps) {
// You don't have to do this check first, but it can help prevent an unneeded render
if (nextProps.startTime !== this.state.startTime) {
this.setState({ startTime: nextProps.startTime });
}
}
기능 후크 구동 구성 요소에서 다음이됩니다.
// store the startTime prop in local state
const [startTime, setStartTime] = useState(props.startTime)
//
useEffect(() => {
if (props.startTime !== startTime) {
setStartTime(props.startTime);
}
}, [props.startTime]);
setState를 사용하여 상태를 설정하고 useEffect를 사용하여 지정된 소품에 대한 변경 사항을 확인하고 소품 변경시 상태를 업데이트하는 조치를 취합니다.
답변
1. 부모로부터 키를 설정
키가 변경되면 React는 현재 인스턴스를 업데이트하지 않고 새 컴포넌트 인스턴스를 만듭니다. 키는 일반적으로 동적 목록에 사용되지만 여기서도 유용합니다.
2. getDerivedStateFromProps
/ 사용componentWillReceiveProps
어떤 이유로 키가 작동하지 않는 경우 (아마도 구성 요소가 초기화하는 데 너무 비쌉니다)
를 사용 getDerivedStateFromProps
하면 상태의 일부를 재설정 할 수 있지만 현재 약간 버그가 있습니다 (v16.7) ! , 사용법에 대해서는 위의 링크를 참조하십시오
답변
반응 문서에서 : https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html
소품 변경시 소거 상태가 안티 패턴
React 16부터 componentWillReceiveProps는 더 이상 사용되지 않습니다. 반응 문서 에서이 경우 권장되는 접근 방식은 사용입니다.
- 완전 구성 요소 제어 다음
ParentComponent
의가ModalBody
자신의 것입니다start_time
상태. 이것은 모달 이이 상태를 소유해야한다고 생각하기 때문에이 경우에는 선호하는 접근법이 아닙니다. - 키가있는 완전히 제어되지 않은 구성 요소 : 이것은 내가 선호하는 접근법입니다. :의 예는 문서 반응 https://codesandbox.io/s/6v1znlxyxn를 . 당신은 당신의
start_time
상태를 완전히 소유하고 이미했던 것처럼ModalBody
사용getInitialState
합니다.start_time
상태 를 재설정하려면 간단히ParentComponent