代码之家  ›  专栏  ›  技术社区  ›  MatTaNg

屈服的人总是被叫来

  •  -1
  • MatTaNg  · 技术社区  · 7 年前

    我正在尝试学习react redux saga;所以我正在构建一个简单的应用程序,它调用一个随机的用户配置文件api并显示它。基本上,当用户点击“下一个图像”按钮时,它应该进行一个REST调用并检索下一个图像。我可以进行API调用并显示信息,但它不断无限地调用API,数据不断变化,尽管没有单击任何东西。这是我的代码:

    应用程序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调用停止。我还在mapsdispatchtoprops中放置了一个日志,以验证它只发送下一个映像操作一次。

    以下是我的行动:

      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()
      ])
    }
    

    我怀疑这与我的传奇中的手表计时功能有关。这就是将手表放在下一个映像操作上,然后调用fetchImage(如果发生)。但是,我不明白为什么它会一直调用fetchImage,如果我只发送下一个映像操作一次。。。

    这是我的减速机和图像发生器-可能没什么有趣的:

    减速机.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;
    

    图像生成器.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 回复  |  直到 7 年前
        1
  •  1
  •   tpdietz    7 年前

    改变 rootSaga 仅限 yield watchNextImage (传奇故事)。你不需要 产量 fetchImage (副作用)。

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

    之后,您只需要在组件中正确地连接您的操作。