yield takeEvery продолжает вызываться - PullRequest
0 голосов
/ 26 августа 2018

Я пытаюсь научиться реагировать на реду-сагу;поэтому я создаю простое приложение, которое вызывает случайный пользовательский профиль API и просто отображает его.В основном, когда пользователь нажимает кнопку «следующее изображение», он должен выполнить вызов REST и получить следующее изображение.Я смог сделать вызов API и отобразить информацию, но он продолжает бесконечно вызывать API, и данные постоянно меняются, несмотря на то, что они ничего не нажимают.Вот мой код:

App.js (родительский компонент)

class App extends Component {
  constructor(props) {
    super(props);
}

  render() {
    return (
        <div className="App">
          <p className="App-intro">
           { this.props.user !== undefined ?  <ImageGenerator user={this.props.user}></ImageGenerator> : <span></span>}
          </p>
        </div>
    );
  }
}

const mapStateToProps = state => {
  return { user: state.value };
};

const mapDispatchToProps = dispatch => {
  return {
      getNewImage: () =>
          dispatch({
              type: NEXT_IMAGE
          })
  }
};

export default connect(mapStateToProps, mapDispatchToProps)(App);

Этот компонент выполняет вызов API и передает информацию в компонент ImageGenerator через пользовательскую поддержку.Я заметил, что когда я комментирую строку ImageGenerator, вызовы API прекращаются.Я также поместил журнал в mapDispatchToProps, чтобы убедиться, что он отправляет действие NEXT_IMAGE только один раз.

Вот мои действия:

  export const NEXT_IMAGE = function() { return { type: "NEXT_IMAGE" } };

    export const fetchFailed = function(error) { return { type: "FETCH_FAILED", value: error } };

    export const setImage = function(data) { return {type: "SET_IMAGE", value: data} };

Вот моя сага:

export function* fetchImage() {
  try {
    const response = yield call(fetch, 'https://randomuser.me/api/');
    const responseBody = yield response.json();
    console.log("QWERT", responseBody.results);
    yield put(setImage(responseBody.results[0]));
  } catch (e) {
    yield put(fetchFailed(e));
  }
  return;

}

export function* watchNextImage() {
  yield takeEvery(NEXT_IMAGE, fetchImage);
}

export default function* rootSaga() {
  yield all([
    fetchImage(),
    watchNextImage()
  ])
}

У меня есть подозрение, что это связано с моей функцией watchNextImage в моей саге.Это то, что отслеживает действие NEXT_IMAGE, а затем вызывает fetchImage, если оно происходит.Однако я не понимаю, почему он продолжал бы вызывать fetchImage, если бы я отправил действие NEXT_IMAGE только один раз ...

Вот мой редуктор и мой ImageGenerator..js:

  const rootReducer = (state = {}, action) => {
          switch(action.type) {
              case NEXT_IMAGE: {
                  return Object.assign({}, state, action)
              }
              case "FETCH_FAILED": {
                  return state;
              }
              case "SET_IMAGE": {
                return Object.assign({}, state, action)
              }
              default: {
                  return state;
              }
          }
      };

      export default rootReducer;

ImageGenerator.js:

class ImageGenerator extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        let user = this.props.user;
        console.log("USer", user);
        return (
            <div>
                Name: {user.name.first} {user.name.last} <br />
                Phone: {user.phone} <br />
                Date of Birth: {user.dob.date} <br/>
                Age: {user.dob.age} <br/>
                Email: {user.email} <br />
                Gender: {user.gender} <br/>
                City: {user.location.city } <br />
                State: {user.location.State } <br />
                Street: {user.location.street } <br />
                <img src={user.picture.medium} alt="No Image Found"/>
                <button onClick={NEXT_IMAGE}>New Image</button>
                <button>Add to Favorites</button> 
           </div>
        )
    }
}

export default ImageGenerator

1 Ответ

0 голосов
/ 28 августа 2018

Измените rootSaga на yield watchNextImage (сага).Вам не нужно yield fetchImage (побочный эффект).

export default function* rootSaga() {
  yield all([
    spawn(watchNextImage)
  ])
}

После этого вам просто нужно правильно подключить свое действие к компоненту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...