react-redux:在API调用后呈现组件

时间:2018-09-16 19:07:13

标签: reactjs react-redux conditional-rendering

我正在构建一个使用用户输入并显示食谱数量的应用程序,他们也可以单击食谱卡来查看配料。每次他们单击配方卡时,我都会进行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);

1 个答案:

答案 0 :(得分:1)

不能完全确定为什么在这里需要Redux(除非在其他嵌套组件之间共享它),但是我确定您可以利用React状态。


一种方法是按以下方式配置您的路由:

    <Route path="/recipes" component={Recipes} />
    <Route path="/recipe/:id" component={ShowRecipe} />

当用户发送查询时,会得到一些结果,然后您将所有匹配的配方显示到Recipes组件中。每个recipe都有一个名称(以及其他关联的可显示数据)和一个可点击的链接:

 <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>

当用户单击链接时,react-router将用户带到具有唯一ShowRecipe的{​​{1}}组件。

ShowRecipe然后发出另一个AJAX请求以获取配方详细信息:

ShowRecipe.js

recipeId

另一种方法:

已将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 JSON中可用。然后映射到recipes上,并为每个recipes创建多个<Card key={recipeId} recipeName={recipeName} recipeDetail={recipeDetail} />组件。

为简单起见,它看起来像:

recipe

然后每张卡都有其自己的状态:

Card.js

<div>
  {this.state.recipes.map(({recipeId, recipeName, recipeDetail}), => (
    <Card key={recipeId} recipeName={recipeName} recipeDetail={recipeDetail} />
  )}
</div>

因此,默认情况下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,以显示/隐藏配方详细信息。