react-redux:在 API 调用后渲染组件
react-redux: Rendering a component after an API call
我正在构建一个使用用户输入并显示食谱数量的应用程序,他们也可以点击食谱卡片来查看配料。每次他们点击食谱卡时,我都会拨打 API 电话以获取合适的食谱成分。但我无法弄清楚如何显示包含配方成分的组件。我也尝试了条件路由和条件渲染,但找不到解决方案。
Recipe_Template.js
export class RecipeTemplate extends Component {
renderRecipe = recipeData => {
return recipeData.recipes.map(recipeName => {
return (
<div className="container">
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<a
href={recipeName.source_url}
target="_blank"
onClick={() => {
this.props.fetchRecipeId(recipeName.recipe_id);
}}
>
<img
src={recipeName.image_url}
className="mx-auto d-block img-fluid img-thumbnail"
alt={recipeName.title}
/>
<span>
<h3>{recipeName.title}</h3>
</span>
</a>
<span}>
<h3>{recipeName.publisher}</h3>
</span>
</div>
</div>
</div>
);
});
};
render() {
return (
<React.Fragment>
{this.props.recipe.map(this.renderRecipe)}
</React.Fragment>
);
}
}
Recipe_Detail.js
class RecipeDetail extends Component {
renderRecipeDetail(recipeData) {
return recipeData.recipe.ingredients.map(recipeIngredient => {
return <li key={recipeIngredient}>recipeIngredient</li>;
});
}
render() {
if (this.props.recipeId === null) {
return <div>Loading...</div>;
}
return <ul>{this.props.recipeId.map(this.renderRecipeDetail)}</ul>;
}
}
function mapStateToProps({ recipeId }) {
return { recipeId };
}
export default connect(mapStateToProps)(RecipeDetail);
不完全确定你为什么需要 Redux(除非它在其他嵌套组件之间共享),但我相当确定你可以只使用 React state。
一种方法是这样配置您的路线:
<Route path="/recipes" component={Recipes} />
<Route path="/recipe/:id" component={ShowRecipe} />
当用户发送查询并获得一些结果时,您将所有匹配的食谱显示到 Recipes
组件。每个 recipe
然后都有一个名称(和其他相关的可显示数据)和一个可点击的 link:
<Link to={`/recipe/id?recipeId=${recipeId}`}>View {recipeName} Recipe</Link>
为了简单起见,它可能看起来像:
<ul>
<Link to="/recipe/id?recipeId=08861626">View Prosciutto Bruschetta Recipe</Link>
<Link to="/recipe/id?recipeId=04326743">View Pasta Bundt Loaf Recipe</Link>
...etc
</ul>
当用户点击 link 时,react-router 将用户发送到具有唯一 recipeId
.
的 ShowRecipe
组件
ShowRecipe 然后发出另一个 AJAX 请求以获取食谱详细信息:
ShowRecipe.js
export default class ShowRecipe extends Component {
state = { recipeDetail: '' }
componentDidMount = () => {
const { recipeId } = this.props.location.query; // <== only natively available in react-router v3
fetch(`http://someAPI/recipe/id?recipeId=${recipeId}`)
.then(response => response.json())
.then(json => this.setState({ recipeDetail: json }));
}
render = () => (
!this.state.recipeDetails
? <div>Loading...</div>
: <ul>
{this.state.recipeDetail.map(ingredient => (
<li key={ingredient}>ingredient</li>
)}
</ul>
)
}
另一种方法:
将 recipeDetails
存储在原始提取的 recipes
JSON 中并可用。然后映射 recipes
并为每个 recipe
.
创建多个 <Card key={recipeId} recipeName={recipeName} recipeDetail={recipeDetail} />
组件
为了简单起见,它可能看起来像:
<div>
{this.state.recipes.map(({recipeId, recipeName, recipeDetail}), => (
<Card key={recipeId} recipeName={recipeName} recipeDetail={recipeDetail} />
)}
</div>
然后每张卡片都有自己的状态:
Card.js
export default class Card extends Component {
state = { showDetails: '' }
toggleShowDetails = () => this.setState(prevState => ({ showDetails: !this.state.showDetails }))
render = () => (
<div>
<h1>{this.props.recipeName} Recipe</h1>
<button onClick={toggleShowDetails}> {`${!this.state.showDetails ? "Show" : "Hide"} Recipe<button>
{ this.state.showDetails &&
<ul>
{this.props.recipeDetail.map(ingredient => (
<li key={ingredient}>ingredient</li>
)}
</ul>
}
)
}
因此,默认情况下 recipeDetail
已经存在,但隐藏了。但是,当用户单击卡片的按钮时,它会将卡片的 showDetails
状态切换为 true/false
到 display/hide 配方详细信息。
我正在构建一个使用用户输入并显示食谱数量的应用程序,他们也可以点击食谱卡片来查看配料。每次他们点击食谱卡时,我都会拨打 API 电话以获取合适的食谱成分。但我无法弄清楚如何显示包含配方成分的组件。我也尝试了条件路由和条件渲染,但找不到解决方案。
Recipe_Template.js
export class RecipeTemplate extends Component {
renderRecipe = recipeData => {
return recipeData.recipes.map(recipeName => {
return (
<div className="container">
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<a
href={recipeName.source_url}
target="_blank"
onClick={() => {
this.props.fetchRecipeId(recipeName.recipe_id);
}}
>
<img
src={recipeName.image_url}
className="mx-auto d-block img-fluid img-thumbnail"
alt={recipeName.title}
/>
<span>
<h3>{recipeName.title}</h3>
</span>
</a>
<span}>
<h3>{recipeName.publisher}</h3>
</span>
</div>
</div>
</div>
);
});
};
render() {
return (
<React.Fragment>
{this.props.recipe.map(this.renderRecipe)}
</React.Fragment>
);
}
}
Recipe_Detail.js
class RecipeDetail extends Component {
renderRecipeDetail(recipeData) {
return recipeData.recipe.ingredients.map(recipeIngredient => {
return <li key={recipeIngredient}>recipeIngredient</li>;
});
}
render() {
if (this.props.recipeId === null) {
return <div>Loading...</div>;
}
return <ul>{this.props.recipeId.map(this.renderRecipeDetail)}</ul>;
}
}
function mapStateToProps({ recipeId }) {
return { recipeId };
}
export default connect(mapStateToProps)(RecipeDetail);
不完全确定你为什么需要 Redux(除非它在其他嵌套组件之间共享),但我相当确定你可以只使用 React state。
一种方法是这样配置您的路线:
<Route path="/recipes" component={Recipes} />
<Route path="/recipe/:id" component={ShowRecipe} />
当用户发送查询并获得一些结果时,您将所有匹配的食谱显示到 Recipes
组件。每个 recipe
然后都有一个名称(和其他相关的可显示数据)和一个可点击的 link:
<Link to={`/recipe/id?recipeId=${recipeId}`}>View {recipeName} Recipe</Link>
为了简单起见,它可能看起来像:
<ul>
<Link to="/recipe/id?recipeId=08861626">View Prosciutto Bruschetta Recipe</Link>
<Link to="/recipe/id?recipeId=04326743">View Pasta Bundt Loaf Recipe</Link>
...etc
</ul>
当用户点击 link 时,react-router 将用户发送到具有唯一 recipeId
.
ShowRecipe
组件
ShowRecipe 然后发出另一个 AJAX 请求以获取食谱详细信息:
ShowRecipe.js
export default class ShowRecipe extends Component {
state = { recipeDetail: '' }
componentDidMount = () => {
const { recipeId } = this.props.location.query; // <== only natively available in react-router v3
fetch(`http://someAPI/recipe/id?recipeId=${recipeId}`)
.then(response => response.json())
.then(json => this.setState({ recipeDetail: json }));
}
render = () => (
!this.state.recipeDetails
? <div>Loading...</div>
: <ul>
{this.state.recipeDetail.map(ingredient => (
<li key={ingredient}>ingredient</li>
)}
</ul>
)
}
另一种方法:
将 recipeDetails
存储在原始提取的 recipes
JSON 中并可用。然后映射 recipes
并为每个 recipe
.
<Card key={recipeId} recipeName={recipeName} recipeDetail={recipeDetail} />
组件
为了简单起见,它可能看起来像:
<div>
{this.state.recipes.map(({recipeId, recipeName, recipeDetail}), => (
<Card key={recipeId} recipeName={recipeName} recipeDetail={recipeDetail} />
)}
</div>
然后每张卡片都有自己的状态:
Card.js
export default class Card extends Component {
state = { showDetails: '' }
toggleShowDetails = () => this.setState(prevState => ({ showDetails: !this.state.showDetails }))
render = () => (
<div>
<h1>{this.props.recipeName} Recipe</h1>
<button onClick={toggleShowDetails}> {`${!this.state.showDetails ? "Show" : "Hide"} Recipe<button>
{ this.state.showDetails &&
<ul>
{this.props.recipeDetail.map(ingredient => (
<li key={ingredient}>ingredient</li>
)}
</ul>
}
)
}
因此,默认情况下 recipeDetail
已经存在,但隐藏了。但是,当用户单击卡片的按钮时,它会将卡片的 showDetails
状态切换为 true/false
到 display/hide 配方详细信息。