如何使用 api 的数据初始化状态
How to initialize state with api's data
我正在创建一个从 api (pokeapi.co) 获取数据的 React/Redux 应用程序。我使用 axios
获取数据。当我在 React 组件上显示数据时,会导致数据为 undefined
的错误。经过一番挖掘,我发现我的状态首先是 returns 初始状态,它是空对象,然后是 returns api 数据。但它不会显示反应。我是 React 的新手,所以我猜它与 axios 异步功能有关。如何使用 api 的初始数据设置状态或等待渲染数据直到状态具有 api 的数据?
这里是 Reducer
function pokemonReducer(state={}, action) {
switch (action.type) {
case pokemonsActions.GET_POKEMON_SUCCESS:
{
return {...state, data: action.payload.data}
}
default:
{
return state;
}
}
}
export default pokemonReducer
这是动作
export const GET_POKEMON_SUCCESS = 'GET_POKEMON_SUCCESS'
export const GET_POKEMON_ERROR = 'GET_POKEMON_ERROR'
function getPokemonSuccess(response) {
return {
type: GET_POKEMON_SUCCESS,
payload: response
}
}
function getPokemonError(err) {
return {
type: GET_POKEMON_ERROR,
payload: err
}
}
export function getPokemon() {
return (disp,getState) =>
{
return pokeAPI.getPokeAPI()
.then((response) => { disp(getPokemonSuccess(response))})
.catch((err)=> disp(getPokemonError(err)))
}
}
店铺
const loggerMiddleware = createLogger()
const middleWare= applyMiddleware(thunkMiddleware,loggerMiddleware);
const store = createStore(rootReducer,preloadedState,
compose(middleWare, typeof window === 'object' && typeof window.devToolsExtension !== 'undefined'
? window.devToolsExtension() : (f) => f
))
const preloadedState=store.dispatch(pokemonActions.getPokemon())
export default store
在 React 组件中
function mapStateToProps(state) {
return {
pokemons:state.pokemons
}
}
class PokemonAbility extends React.Component {
render(){
return (
<div>
<div className="header">
<h1>Fetch Poke Api with axios</h1>
</div>
<main>
<h3> Display pokemons abilities </h3>
<p>{this.props.pokemons.data.count}</p>
</main>
</div>
)
}
}
export default connect(
mapStateToProps
)(PokemonAbility)
Api数据示例
{
"count": 292,
"previous": null,
"results": [
{
"url": "https://pokeapi.co/api/v2/ability/1/",
"name": "stench"
},
{
"url": "https://pokeapi.co/api/v2/ability/2/",
"name": "drizzle"
},
{
"url": "https://pokeapi.co/api/v2/ability/3/",
"name": "speed-boost"
}
],
"next": "https://pokeapi.co/api/v2/ability/?limit=20&offset=20"
}
您在数据加载之前呈现您的组件。有很多策略可以解决这个问题。排名不分先后,以下是一些示例:
1。将渲染器短路
如果数据不存在,您可以通过返回加载消息来短路渲染:
function mapStateToProps(state) {
return {
pokemons:state.pokemons
}
}
class PokemonAbility extends React.Component {
render(){
if (!this.props.pokemons.data) {
return (
<div>Loading...</div>
);
}
return (
<div>
<div className="header">
<h1>Fetch Poke Api with axios</h1>
</div>
<main>
<h3> Display pokemons abilities </h3>
<p>{this.props.pokemons.data.count}</p>
</main>
</div>
);
}
}
export default connect(mapStateToProps)(PokemonAbility);
2。将数据检查提升到父组件
可以将mapStateToProps
移动到更高的组件,或者抽象出视图组件,只在数据准备好时渲染视图:
function mapStateToProps(state) {
return {
pokemons:state.pokemons
}
}
class SomeHigherComponent extends React.Component {
render(){
return (
this.props.pokemons.data ?
<PokemonAbility pokemons={this.props.pokemons} /> :
<div>Loading...</div>
);
}
}
3。高阶组件数据检查
您可以将您的组件包装在 "higher order component" 中(一个接受组件 class 和 returns 组件 class 的函数)以检查该 prop 之前是否存在渲染:
function EnsurePokemon(ChildComponent) {
return class PokemonEnsureWrapper extends React.Component {
render() {
return (
this.props.pokemons.data ?
<ChildComponent {...this.props} /> :
<div>Loading...</div>
);
}
}
}
用法:
export default connect(
mapStateToProps
)(EnsurePokemon(PokemonAbility))
并且您可以在此 EnsurePokemon
HOC 中包装任何子组件,以确保它在数据加载之前不会呈现。
我正在创建一个从 api (pokeapi.co) 获取数据的 React/Redux 应用程序。我使用 axios
获取数据。当我在 React 组件上显示数据时,会导致数据为 undefined
的错误。经过一番挖掘,我发现我的状态首先是 returns 初始状态,它是空对象,然后是 returns api 数据。但它不会显示反应。我是 React 的新手,所以我猜它与 axios 异步功能有关。如何使用 api 的初始数据设置状态或等待渲染数据直到状态具有 api 的数据?
这里是 Reducer
function pokemonReducer(state={}, action) {
switch (action.type) {
case pokemonsActions.GET_POKEMON_SUCCESS:
{
return {...state, data: action.payload.data}
}
default:
{
return state;
}
}
}
export default pokemonReducer
这是动作
export const GET_POKEMON_SUCCESS = 'GET_POKEMON_SUCCESS'
export const GET_POKEMON_ERROR = 'GET_POKEMON_ERROR'
function getPokemonSuccess(response) {
return {
type: GET_POKEMON_SUCCESS,
payload: response
}
}
function getPokemonError(err) {
return {
type: GET_POKEMON_ERROR,
payload: err
}
}
export function getPokemon() {
return (disp,getState) =>
{
return pokeAPI.getPokeAPI()
.then((response) => { disp(getPokemonSuccess(response))})
.catch((err)=> disp(getPokemonError(err)))
}
}
店铺
const loggerMiddleware = createLogger()
const middleWare= applyMiddleware(thunkMiddleware,loggerMiddleware);
const store = createStore(rootReducer,preloadedState,
compose(middleWare, typeof window === 'object' && typeof window.devToolsExtension !== 'undefined'
? window.devToolsExtension() : (f) => f
))
const preloadedState=store.dispatch(pokemonActions.getPokemon())
export default store
在 React 组件中
function mapStateToProps(state) {
return {
pokemons:state.pokemons
}
}
class PokemonAbility extends React.Component {
render(){
return (
<div>
<div className="header">
<h1>Fetch Poke Api with axios</h1>
</div>
<main>
<h3> Display pokemons abilities </h3>
<p>{this.props.pokemons.data.count}</p>
</main>
</div>
)
}
}
export default connect(
mapStateToProps
)(PokemonAbility)
Api数据示例
{
"count": 292,
"previous": null,
"results": [
{
"url": "https://pokeapi.co/api/v2/ability/1/",
"name": "stench"
},
{
"url": "https://pokeapi.co/api/v2/ability/2/",
"name": "drizzle"
},
{
"url": "https://pokeapi.co/api/v2/ability/3/",
"name": "speed-boost"
}
],
"next": "https://pokeapi.co/api/v2/ability/?limit=20&offset=20"
}
您在数据加载之前呈现您的组件。有很多策略可以解决这个问题。排名不分先后,以下是一些示例:
1。将渲染器短路
如果数据不存在,您可以通过返回加载消息来短路渲染:
function mapStateToProps(state) {
return {
pokemons:state.pokemons
}
}
class PokemonAbility extends React.Component {
render(){
if (!this.props.pokemons.data) {
return (
<div>Loading...</div>
);
}
return (
<div>
<div className="header">
<h1>Fetch Poke Api with axios</h1>
</div>
<main>
<h3> Display pokemons abilities </h3>
<p>{this.props.pokemons.data.count}</p>
</main>
</div>
);
}
}
export default connect(mapStateToProps)(PokemonAbility);
2。将数据检查提升到父组件
可以将mapStateToProps
移动到更高的组件,或者抽象出视图组件,只在数据准备好时渲染视图:
function mapStateToProps(state) {
return {
pokemons:state.pokemons
}
}
class SomeHigherComponent extends React.Component {
render(){
return (
this.props.pokemons.data ?
<PokemonAbility pokemons={this.props.pokemons} /> :
<div>Loading...</div>
);
}
}
3。高阶组件数据检查
您可以将您的组件包装在 "higher order component" 中(一个接受组件 class 和 returns 组件 class 的函数)以检查该 prop 之前是否存在渲染:
function EnsurePokemon(ChildComponent) {
return class PokemonEnsureWrapper extends React.Component {
render() {
return (
this.props.pokemons.data ?
<ChildComponent {...this.props} /> :
<div>Loading...</div>
);
}
}
}
用法:
export default connect(
mapStateToProps
)(EnsurePokemon(PokemonAbility))
并且您可以在此 EnsurePokemon
HOC 中包装任何子组件,以确保它在数据加载之前不会呈现。