根据子组件菜单选项更改父组件中显示的json内容

时间:2019-07-01 22:50:10

标签: json reactjs

我在Navbar组件中有一个带有下拉菜单的应用程序,其中包含衣服尺寸(S,M,L)。所有服装都在json的父App组件中呈现。我想重新渲染App组件的部分,该部分根据菜单选择显示包含json中的项目的项目。任何提示表示赞赏。

我正在从json渲染所有内容,并在下拉菜单更改时更新状态,但无法重新渲染父组件中的产品(显示在网格中)

JSON

const tops =  [{
            index: 0,
            isSale: true,
            isExclusive: false,
            price: "$18.88",
            productImage: "product-1.jpg",
            productName: "Striped top",
            size: ["XS", "S", "L", "XL"]
          },
          {
            index: 1,
            isSale: false,
            isExclusive: false,
            price: "$25.44",
            productImage: "product-2.jpg",
            productName: "Denim top",
            size: ["XS", "S"]
          },
          {
            index: 2,
            isSale: false,
            isExclusive: true,
            price: "$12.93",
            productImage: "product-3.jpg",
            productName: "Plain cotton top",
            size: ["S", "M"]
...
          }];

顶部,导航栏和应用程序组件

let saleExclusive = null;

class Top extends Component {

            constructor(props) {
              super(props);

              this.state = {
                              id: null, 
                              productName: null,
                              productImage: null,
                              isSale: null,
                              isExclusive: null,
                              size: null,
                              price: null,
                              saleExclusive: null
              }
            }

              render (){

                if(this.props.isSale===true){
                      saleExclusive = <div className="btn btn-danger m20">Sale</div>
                    } 
                    else if(this.props.isExclusive===true){
                      saleExclusive = <div className="btn btn-success m20">Exclusive</div>
                    } 
                    else {
                      saleExclusive = <div className="blank"></div>
                }

              return (
                <div className="col-3 displayBox">
                  <div className="row text-center"><img src={require("./assets/images/"+this.props.productImage)} width="90%" height="90%" alt="Select this" /></div>
                  <div className="row">
                    {  saleExclusive }  
                  </div>
                  <div className="row h50">
                  <div className="col-7 text-left prod-desc">{this.props.productName}</div>
                  <div className="col-3 prod-price">{this.props.price}</div>
                  </div>
                </div>
              );
            }
          }


class NavBar extends Component {

            constructor(props) {
                super(props);

            this.state = {
                selectValue: '',
                selectedSize: '',
                data:''
                }
            }



              componentDidUpdate(){
                console.log(this.state.selectedSize)
              }

            render (){
              var handleChange  =   this.props.handleChange;
                return( <div className="row navbarpoz">
                                <div className="col-6 text-left heading">
                                {this.props.navTitle}
                                </div>
                                <div className="col-6 text-right">
                                    <select id="availablesizes"   
                                            defaultValue={this.selectValue} 
                                            onChange={() => handleChange(this.value)}>
                                        <option>Filter by size</option>
                                        <option value="XS">XS</option>
                                        <option value="S">S</option>
                                        <option value="M">M</option>
                                        <option value="L">L</option>
                                        <option value="XL">XL</option>
                                    </select>
                                </div>
                            </div>
                    );
              }
        }     

class App extends Component {

            constructor(props){
              super(props);
              this.handleChange = this.handleChange.bind(this);
              this.state = {
                data: "...let's shop",
                selectedSize: ''
              }
            }

            handleChange(size) {
              this.setState({
                selectedSize: size
              })
              alert(size);
            }

            getData(){
              setTimeout(() => {
                this.setState({
                  data: "Women's tops",
                  selectedSize: 'S'
                })
              }, 1000)
            }

            componentDidMount(){
              this.getData();
            }

    render() { 
    return (
            <div className="container">
              {this.state.selectedSize}
                <NavBar navTitle={this.state.data}/>
                <div id="itemGrid" className="text-center">
                {tops.map(tops => (
                    <Top handleChange={this.handleChange} 
                        key={tops.id} 
                        productName={tops.productName}
                        productImage={tops.productImage}
                        isSale={tops.isSale}
                        isExclusive={tops.isExclusive}
                        size={tops.size}
                        price={tops.price}
                    />
                ))}
                </div>            
            </div>
            );
        }
    }


export default App

当用户从菜单中选择XS时,只有大小为[“ XS”]的json需要显示在网格中。目前,父母还没有更新。

1 个答案:

答案 0 :(得分:1)

<select />的{​​{1}}中,您使用的是Navbar,但此处的this.value是指未设置任何{{1 }},因此始终为this

Navbar

您要执行的操作是:

value

然后在您的null中,您需要用onChange={() => handleChange(this.value)}> 状态过滤onChange={event => handleChange(event.taget.value)}>

App

在映射它之前,就像在tops中所做的那样:

selectedSize

但是在用户选择大小之前,结果将为空,因为const suitableTops = tops.filter(top => top.size.includes(this.state.selectedSize)); 默认为render,因此您可能希望将现有大小默认设置为suitableTops.map(top => <Top key={top.id} {...top} />); 状态。或将过滤器包裹起来。