代码之家  ›  专栏  ›  技术社区  ›  The Walrus

在React中切换类并设置活动类

  •  0
  • The Walrus  · 技术社区  · 7 年前

    我知道如何在React中切换类,也知道如何激活类。然而,我不知道如何将两者结合在一起。

    我映射我的食谱并渲染每一个。我想在单击一个配方后将其展开,如果再次单击,则返回到其自然状态。但是,如果我打开了一个配方,并点击了另一个配方的展开,那么它应该关闭第一个配方,然后展开新的配方。

    这是我的整个组件:

    state = {
        term: '',
        selectedRecipeId: 0
      }
    
      handleInput = (e) => {
        const { value } = e.target;
        this.setState({term: value})
      }
    
      expandRecipe = (recipeId) => {
        this.setState({ selectedRecipeId: recipeId })
      }
    
      renderExpandedView = (recipe) => {
        if (this.state.selectedRecipeId === recipe.id){
          return 'recipeContainerExpanded'
        }
        else {
          return null
        }
      }
    
      resetView = () => {
        this.setState({selectedRecipeId: 0})
      }
    
      render(){
        const { recipes } = this.props;
        const { term } = this.state;
        return (
          <div>
            <h1>Recipes</h1>
            <button onClick={this.resetView}>Reset View</button>
            <input onChange={this.handleInput} />
            <div className="recipesContainer">
              {recipes.filter(recipe => recipe.name.toLowerCase().includes(term.toLowerCase()) || recipe.ingredients.some(ingredient => ingredient.startsWith(term.toLowerCase()))).map((recipe, index) => (
                <div key={index} className={`recipeContainer ${this.renderExpandedView(recipe)}`}>
                  <h3>{recipe.name}</h3>
                  <button onClick={() => this.expandRecipe(recipe.id)}>Expand</button>
                  <h4>Ingredients</h4>
                  <p>{recipe.ingredients.map(ingredient => <p>{ingredient}</p>)}</p>
                </div>
              ))}
            </div>
          </div>
        )
      }
    

    此代码将展开一个配方,然后如果单击另一个配方,它将展开该配方并关闭前一个配方。我只想在第二次单击时添加功能,关闭该配方,但如果不将javascript应用于每个配方,我无法完成该操作。

    希望这有意义

    3 回复  |  直到 7 年前
        1
  •  0
  •   Igor Alemasow    7 年前

    您可以将配方提取到 配方 组件和用途 应更新组件 生命周期方法,让React知道组件输出是否不受当前更改道具的影响。

    export default class Recipe extends Component {
    expandRecipe = () => {
        const {onExpand, recipe, isExpanded} = this.props;
    
        onExpand(isExpanded ? null : recipe.id);
    };
    
    shouldComponentUpdate(nextProps) {
        const {isExpanded} = this.props;
    
        return isExpanded !== nextProps.isExpanded;
    }
    
    render() {
        const {recipe, isExpanded} = this.props;
    
        return (
            <div className={`recipeContainer ${isExpanded ? 'recipeContainerExpanded' : ''}`}>
                <h3>{recipe.name}</h3>
                <button onClick={this.expandRecipe}>Expand</button>
                <h4>Ingredients</h4>
                <p>{recipe.ingredients.map(ingredient => <p>{ingredient}</p>)}</p>
            </div>
        )
    }
    }
    

    请检查一下 demo

        2
  •  0
  •   Jayavel    7 年前

    我刚刚用我的假设做了一个演示检查链接: demo

    这是你需要的吗?或者给我更多细节来解决这个问题

        3
  •  0
  •   Muneeb    7 年前

    创建负责可扩展的单独组件。

    可扩展。js公司

    class Expandable extends React.PureComponent {
    constructor() {
    super();
    this.state = {
      isExpand: true,
      selectedRecipeId: 0,
    };
    this.togglePar = :: this.expandRecipe;
    }
    expandRecipe(recipeId) {
    this.setState({
      isExpand: !this.state.isPar,
      selectedRecipeId: recipeId,
    });
    }
    render() {
     return (
      <div>
        <h3>{this.props.name}</h3>
        <button onClick={() => this.expandRecipe(this.props.id)}>Expand</button>
        {this.state.isExpand && <div>
          <h4>Ingredients</h4>
          <p>{this.props.ingredients.map(ingredient => <p>{ingredient}</p>)}</p>
          </div>
         }
        </div>
       );
      }
    }
    

    实际组件

      render() {
      const { recipes } = this.props;
      const { term } = this.state;
      return (
      <div>
        <h1>Recipes</h1>
        <button onClick={this.resetView}>Reset View</button>
        <input onChange={this.handleInput} />
        <div className="recipesContainer">
          {recipes.filter(recipe => 
          recipe.name.toLowerCase().includes(term.toLowerCase()) || 
          recipe.ingredients.some(ingredient => 
          ingredient.startsWith(term.toLowerCase()))).map((recipe, index) => (
            <Expandable key={index} props... />
          ))}
        </div>
      </div>
     )
    }