Redux에서 상태를 업데이트 한 후 콜백을 트리거하는 방법은 무엇입니까?


86

React에서는 상태가 즉시 업데이트되지 않으므로 setState(state, callback). 하지만 Redux에서 어떻게할까요?

를 호출 한 후 this.props.dispatch(updateState(key, value))즉시 업데이트 된 상태로 무언가를해야합니다.

React에서하는 것과 같은 최신 상태로 콜백을 호출 할 수있는 방법이 있습니까?


사용 thunk합니까?
Pranesh 라비

1
dispatch()동기식 활동 이라고 생각 합니다. 업데이트 된 상태는 다음 줄에서 사용할 수 있습니다.
Pranesh 라비

4
@PraneshRavi 그렇게 생각했습니다. 그러나 나는 오래된 상태를 얻었다. 나는 thunk.
벽돌 양


1
예, 디스패치는 동기식이지만 구성 요소 소품의 후속 업데이트는 그렇지 않습니다. 따라서 redux 상태는 다음 줄에서 업데이트되지만 구성 요소의 props는 아직 업데이트되지 않았습니다.
amik

답변:


113

새 소품을 받으려면 구성 요소를 업데이트해야합니다.

목표를 달성하는 방법이 있습니다.

1. componentDidUpdate 값이 변경되었는지 확인한 다음 작업을 수행합니다.

 componentDidUpdate(prevProps){
     if(prevProps.value !== this.props.value){ alert(prevProps.value) }
  }

2. redux-promise (미들웨어가 promise 의 해결 된 값을 전달합니다)

export const updateState = (key, value)=>
Promise.resolve({
  type:'UPDATE_STATE',
  key, value
})

그런 다음 구성 요소

this.props.dispatch(updateState(key, value)).then(()=>{
   alert(this.props.value)
})

2. redux-thunk

export const updateState = (key, value) => dispatch => {
  dispatch({
    type: 'UPDATE_STATE',
    key,
    value,
  });
  return Promise.resolve();
};

그런 다음 구성 요소

this.props.dispatch(updateState(key, value)).then(()=>{
   alert(this.props.value)
})

6
귀하의 redux-thunk예 에서는 dispatch동기식 인 것처럼 사용 합니다. 그럴까요?
Danny Harding

2
@DannyHarding dispatch은 동기식이 아닙니다. 포함하지 않는 Promise.resolve(), this.props.value여전히 이전 값을 반환합니다. 어떤 종류의 비동기 지연이 여전히 필요합니다 ( setTimeout예를 들어 내부에서 참조하는 것도 작동합니다).
Drazen Bjelovuk

4
@DrazenBjelovuk redux-thunk 예제의 updateState 함수가 dispatch (someAction) 바로 뒤에 Promise.resolve ()를 반환하기 때문에 궁금합니다. 약속은 즉시 해결되며 redux 저장소 업데이트와 구성 요소에서 호출 된. 디스패치는 약속을 반환하거나 콜백을 수락하지 않기 때문에 이것이 redux 저장소가 언제 업데이트되었는지 알 수있는 정확한 방법이라고 생각하지 않습니다. 난 그냥 - 보리스에 의해 대답은이 경우 올바른이라고 생각
대니 하딩에게

2
@DannyHarding 네,이 방법이 확실한 화재 보장이 아니라는 점에 동의합니다.
Drazen Bjelovuk

1
여기서 redux-thunk 솔루션을 사용하려고하는데 TypeError: _this.props.dispatch is not a function?
Krillko

14

React에서 가장 중요한 점은 단방향 데이터 흐름입니다. 귀하의 예에서 즉, 작업 전달 및 상태 변경 처리가 분리되어야 함을 의미합니다.

"내가 그랬던 것처럼 당신은 생각한다 A, 지금 X이된다 Y"어떤 때 내가 어떻게 내가 그것을 처리 "하지만 XY어떤 관계없이" A. 상점 상태는 구성 요소 외에도 여러 소스에서 업데이트 할 수 있으며 시간 여행도 상태를 변경할 수 있으며 A디스패치 지점을 통해 전달되지 않습니다 .

기본적으로 componentWillReceiveProps@Utro가 제안한대로 사용해야 함을 의미합니다.


이것은 op가 정말로 찾고있는 대답입니다 (그가 이것을 알지 못하는 것처럼 보이지만 ..)
refaelio

1
나도 동의하지만이 안티 패턴 고려해야 할 것 같다 hackernoon.com/...
자코모 Cerquone을

1
componentWillReceiveProps더 이상 사용되지 않는 지금 우리는 무엇을합니까 ? static getDerivedStateFromProps()내가 말할 수있는 한 콜백을 호출 할 수 없기 때문에 적절한 대체품이 아닌 것 같습니다
M3RS

10

Hooks API 사용 :

useEffect 소품을 입력으로 사용합니다.

import React, { useEffect} from 'react'
import { useSelector } from 'react-redux'

export default function ValueComponent() {
   const value = useSelector(store => store.pathTo.value)

   useEffect(() => {
     console.log('New value', value) 
     return () => {
        console.log('Prev value', value) 
     }

   }, [value])

   return <div> {value} </div>
}

수락 된 답변은 React Hooks 이전에 작성되었습니다. 이것은 후크를 도입 한 후 이제 받아 들여지는 대답이어야합니다. 변경을 처리하는 더 반응적인 방법입니다.
tif

5

subscribe리스너를 사용할 수 있으며 액션이 전달 될 때 호출됩니다. 리스너 내부에서 최신 매장 데이터를 얻을 수 있습니다.

http://redux.js.org/docs/api/Store.html#subscribelistener


2
subscribe액션이 전달 될 때만 발생합니다. subscribeAPI 호출이 데이터를 반환했는지 알 수있는 방법 은 없습니다 . : D
미 히어

요청이 완료되면 (성공 또는 실패) 다른 작업을 전달할 수 있습니다.
Jam

여기서 제안 된 다른 솔루션이 실제로 작동한다고 확신하지 않습니다. 상태가 업데이트 된 후 해결 약속이나 콜백이 실행되는 방법을 보지 못하기 때문입니다. 이 메서드는 이벤트 이후에 발생하는 업데이트뿐만 아니라 모든 상점 업데이트에 대해 호출되지만 해결하기가 너무 어렵지는 않습니다. 특히 링크 된 페이지에서 사용자 정의 observeStore 유틸리티작성하면 매우 유용합니다.
Nat Kuhn

링크 페이지를 찾을 수 없습니다
바랏 모디를

2

콜백과 함께 썽크를 사용할 수 있습니다.

myThunk = cb => dispatch =>
  myAsyncOp(...)
    .then(res => dispatch(res))
    .then(() => cb()) // Do whatever you want here.
    .catch(err => handleError(err))

내가 필요했던 것에 딱!
JSON C11

-1

간단한 솔루션으로 사용할 수 있습니다. redux-promise

그러나 redux-thunk 를 사용한다면 다음 과 같이해야합니다 :

function addCost(data) {
  return dispatch => {
    var promise1 = new Promise(function(resolve, reject) {
      dispatch(something);
     });
    return promise1;
  }
}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.