所有数据准备就绪后,加载组件

时间:2018-12-18 23:00:35

标签: javascript reactjs redux

我在Redux上使用React。 在此示例中,我的班级有 mapStateToProps mapDispatchToProps

class EnigmaPage extends Component {

    constructor(props){
        super(props);
    }

    componentDidMount() {
        this.props.authCheckState();
    }

    readUserData() {
        this.props.loadLevel(this.props.userId);
    }

    render(){
        return (
            <div className={classes.EnigmaPage}>
                <div className={classes.Header}>
                    <div>
                        <LevelInfo 
                            difficulty={this.props.level.difficulty}
                            level={this.props.level.level}
                            readUserData={this.readUserData()}
                        />

                    </div>
                </div>
            </div>
        )
    }

}

const mapDispatchToProps = dispatch => {
    return {
        authCheckState: () => dispatch(actions.authCheckState()),
        getLevel: () => dispatch(actions.getLevel()),
        loadLevel:(id) => dispatch(actions.loadLevel(id))
    };
}
const mapStateToProps = state => {
    return {
        userId:state.auth.user,
        level:state.level.level
    }
}

我想将值难度 level 推送到组件 LevelInfo ,但这两个数据来自 getLevel()这是一个延迟的http请求。
在从http调用接收所有数据之前,该页面已加载。
我正在寻找一种等待加载组件 LevelInfo 或在数据准备就绪后重新加载组件的方法。

4 个答案:

答案 0 :(得分:6)

您需要告诉您的组件将等待呈现 package bookrental.service.account; import bookrental.model.book.BookRentals; import bookrental.repository.book.BookRentalsRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserRentalsService { private final BookRentalsRepository bookRentalsRepository; @Autowired public UserRentalsService(BookRentalsRepository bookRentalsRepository) { this.bookRentalsRepository = bookRentalsRepository; } public List<BookRentals> findUserRentalsByGivenID(int userID) { return bookRentalsRepository.getUserRentalsByGivenID(userID); } } package bookrental.controller.account; import bookrental.model.book.BookRentals; import bookrental.service.account.UserRentalsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class UserRentalsController { private final UserRentalsService userRentalsService; @Autowired public UserRentalsController(UserRentalsService userRentalsService) { this.userRentalsService = userRentalsService; } @GetMapping("books/rentals/{userID}") public List<BookRentals> findUserRentalsByGivenID(@PathVariable int userID) { return userRentalsService.findUserRentalsByGivenID(userID); } } 组件所需的数据,因此在您的package bookrental.service.book.rentals; import bookrental.model.account.User; import bookrental.model.book.Book; import bookrental.model.book.BookRentals; import bookrental.repository.account.UserRepository; import bookrental.repository.book.BookRepository; import bookrental.repository.book.BookRentalsRepository; import flexjson.JSONSerializer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @Service public class BookRentalService { private final UserRepository userRepository; private final BookRepository bookRepository; private final BookRentalsRepository bookRentalsRepository; @Autowired public BookRentalService(BookRepository bookRepository, BookRentalsRepository bookRentalsRepository, UserRepository userRepository) { this.bookRepository = bookRepository; this.bookRentalsRepository = bookRentalsRepository; this.userRepository = userRepository; } .... public ResponseEntity<String> findAllRentals() { List<BookRentals> rentedBooks = new ArrayList<>(); bookRentalsRepository.findAll().forEach(rentedBooks::add); HttpHeaders headers = new HttpHeaders(); headers.add("Content-Type", "application/json; charset=utf-8"); return new ResponseEntity<>(new JSONSerializer().exclude("book.class") .exclude("book.available") .exclude("dateOfReturn") .exclude("*.class") .exclude("user.amountOfCashToPay") .exclude("password") .serialize(rentedBooks), headers, HttpStatus.OK); } } 组件中编写如下内容

Level

希望它能对您有所帮助。

答案 1 :(得分:2)

我们不让组件等待,而是让初始渲染发生,但是使用条件表达式渲染目标组件。

render() {
  return (
    <div className={classes.EnigmaPage}>
      <div className={classes.Header}>
        <div>
          {this.props.level && (
            <LevelInfo
              difficulty={this.props.level.difficulty}
              level={this.props.level.level}
              readUserData={this.readUserData()}
            />
          )}
        </div>
      </div>
    </div>
  );
}

因此,我们在这里检查是否定义了this.props.level。当它为undefined时,在获取数据LevelInfo组件后,React不呈现任何内容。您可以更改条件渲染逻辑。您可以渲染Loading组件,而不是什么都不要。但是,最终,您将有条件地渲染组件。

答案 2 :(得分:0)

尝试使用conditional rendering

isDataReady() {
    if(this.props.level.difficulty && this.props.level.level)
        return true;
    return false;
}

render(){
    return (
        <div className={classes.EnigmaPage}>
            <div className={classes.Header}>
                <div>
                {this.isDataReady() ? <LevelInfo 
                        difficulty={this.props.level.difficulty}
                        level={this.props.level.level}
                        readUserData={this.readUserData()}
                    />
             : <div> </div>}
                </div>
            </div>
        </div>
    );
}

万一您的数据还没有准备好,您可以显示任何想要的内容,为简单起见,在这里我只添加了一个空的<div>

答案 3 :(得分:0)

Johuder Gonzalez谈到了Spinner。 Material UI有很多示例,很容易应用。请查看以下内容。 Material UI Progress