Estoy tratando de establecer una representación condicional de un objeto anidado asignado. Objeto mapeado:

const products = [
    {category: "Napoje", products:
        {
            product1: "Piwo",
            product2: "Wino",
            product3: "Cola",
            product4: "Sprite"
        }
    },
    {category: "Pieczywo", products:
        {
            product1: "Chleb",
            product2: "Bułka",
            product3: "Chałka",
            product4: "Rogal"
        }
    }
]

Mi código:

class Products extends React.Component{
    constructor(props){
        super(props)
    }
    render(){
        for(var i=0; i<this.props.products.length; i++){
            if (Object.values(this.props.products[i].products).indexOf(this.props.filter)<1) return false;
        }
        return(
            <div>
                {this.props.products
                    .map(product =>
                        <div>
                            {product.category}
                            {Object.values(product.products).map(name => <li>{name}</li>)}
                        </div>
                    )
                }
            </div>
        )
    }
}

¿Cómo puedo arreglar eso? El componente recibe texto de la entrada de búsqueda. La idea es mostrar solo los objetos que contienen la entrada del formulario de texto.

Gracias

Kuba

0
Jakub Matwiejew 14 ene. 2018 a las 23:28

3 respuestas

La mejor respuesta

Aquí hay una versión ligeramente optimizada donde los objetos se asignan a objetos con solo productos coincidentes o null sy luego se filtran solo para los que no son null s:

class Products extends React.Component {
  getFilteredProducts() {
    const filter = this.props.filter;

    const filteredProducts = this.props.products.map(obj => {
        // filter out those that don't match
        const filtered = Object.values(obj.products)
           .filter(p => p.indexOf(filter) > -1);

        // if no match found, exclude from the list entirely
        if (filtered.length === 0) return null;

        // combine into a new object with only filterd products
        return { ...obj, ...{ products: filtered } };
      })
      // filter out objects without any matched products
      .filter(product => product);

      return filteredProducts;
  }
  render() {
    return (
      <div>
        {this.getFilteredProducts()
          .map((product, ind) =>
            <div key={ind}>
              {product.category}
              {Object.values(product.products).map(name => <li>{name}</li>)}
            </div>
          )
        }
      </div>
    )
  }
}
1
margaretkru 14 ene. 2018 a las 20:46

Cuando necesita seleccionar solo ciertos elementos de una matriz, un patrón común y bueno es filtrar la matriz. Aquí hay un código no optimizado:

class Products extends React.Component{
    constructor(props){
        super(props)
    }
    render(){
        return(
            <div>
                {this.props.products
                    .filter(product => Object.values(product.products).filter(
                        productName => productName.indexOf(this.props.filter) === -1 )
                    )
                    .map(product =>
                        <div>
                            {product.category}
                            {Object.values(product.products).map(name => <li>{name}</li>)}
                        </div>
                    )
                }
            </div>
        )
    }
}

Resumiría la función de filtrado en un método:

class Products extends React.Component{
    constructor(props){
        super(props)
    }

    // Return every product name in a category that doesn't match a
    // specified string
    filterProducts(products, testString) {
        return products.filter(product =>
            Object.values(product.products).filter(
                productName => productName.indexOf(testString) === -1
            )
        );
    }

    render(){
        const { products, filter } = this.props;
        return(
            <div>
                {this.filterProducts(prodcts, filter).map(product => (
                    <div>
                        {product.category}
                        {Object.values(product.products).map(name => <li>{name}</li>)}
                    </div>
                )}
            </div>
        )
    }
}
0
Andy Ray 14 ene. 2018 a las 20:34
class Products extends React.Component{
    constructor(props){
        super(props)
    }
    render(){
        return(
            <div>
                {this.props.products
                    .map(product =>
                        <div>
                            {product.category}
                            {Object.values(product.products).map((name) =>{
if(name.indexOf(this.props.filter) === -1) {
return null
}
return (<li>{name}</li>)
} )}
                        </div>
                    )
                }
            </div>
        )
    }
}

Esto puede ayudar

0
simbathesailor 14 ene. 2018 a las 20:36