我在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 或在数据准备就绪后重新加载组件的方法。
答案 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)
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