繁体   English   中英

过滤后的数据没有从 React 中的父组件传递到子组件

[英]filtered data not getting pass from parent component to child component in React

这就是组件的样子,我有 3 个组件参与此任务,每当我选择过滤器组件中的不同 select 下拉选项时,父组件中的更改方法将被触发,并且该方法也会在父组件中调用另一个方法filterData . 它过滤数据,但在设置state后,我没有在子组件中获得过滤数据。 所以我可以显示过滤后的数据

//parent component


import React, { Component } from 'react';
import ListingsData from '../data/data';
import Listings from '../listings/listings.component';
import Filter from '../filters/filter.component';
import './main_content.styles.scss';


class Main_content extends Component {
    constructor(props) {
        super();
        this.state = {
            listingsData: ListingsData,
            searchOnChange: '',
            filterdProperties: ListingsData,
        }
    }

    change = (e) => {
        this.setState({
            [e.target.name] : e.target.value
        }, () => {
                this.filterData();
            }
        )
    }

    filterData = () => {
        let newData = this.state.listingsData.filter(property => {
            return property.type.toLowerCase().toString() === this.state.houseType.toLowerCase().toString()
        })

        this.setState({ filterdProperties: newData }, () => {
            console.log(this.state)
        });
    }

    render() {
        return (
            <div className='main-content'>
                <div className='listings-container'>
                    <Listings ListingsData={ this.state.filterdProperties } />
                </div>
                <div className='filter-sidebar'>
                    <Filter filterTypeHouse={this.change} />
                </div>
            </div>
        );
    }
}

export default Main_content;



//child component Listing.component.jsx

import React, {Component} from 'react';
import './listings.styles.scss';
import Listing from '../listing/listing.component'

class Listings extends Component {
    constructor(props) {
        super(props);
        this.state = {
            listings: props.ListingsData
        }
    }

    render() {
        if (this.state.listings === undefined || this.state.listings.length === 0) {
            return <h2>sorry no data found</h2>
        }

        return (
            <div className='listings'>
                {this.state.listings.map(({ id, image, address, price, city, rooms, bathrooms, area }) => (
                    <Listing key={id} image={image} address={address} price={price} city={city} rooms={rooms} bathrooms={bathrooms} area={area} />
                ))}
            </div>
        )
    }
}

export default Listings;



//child component filter.component.jsx


import React from 'react';
import './filter.styles.scss';

let Filter = (props) => (
    <div className='filter'>
        <div className='type'>
            <label htmlFor='propertyType'>Type</label>
            <select className='propertyType' name='houseType' onChange={props.filterTypeHouse} >
                <option value='any'>Any</option>
                <option value='family-house'>Family House</option>
                <option value='single-house'>Single house</option>
                <option value='apartment'>Apartment</option>
                <option value='villa'>Villa</option>
                <option value='office-building'>Office Building</option>
                <option value='condo'>Condo</option>               
            </select>
        </div>
        <div className='location'>
        <label htmlFor='PropertyLocation'>Location</label>
            <select className='PropertyLocation'>
                <option>Any</option>
                <option>New york</option>
                <option>California</option>
                <option>Washington</option>
                <option>philedelphia</option>
                <option>Boston</option>               
            </select>
        </div>
        <div className='min-price'>
            <label htmlFor='priceFrom'>Min-Price</label>
            <input type='text' className='priceFrom' placeholder='min-price' />
        </div>
        <div className='max-price'>
            <label htmlFor='priceTo'>Max-Price</label>  
            <input type='text' className='priceTo' placeholder='max-price' />
        </div>
        <div className='dealOption'>
            <label htmlFor='options'>Type Of Deal</label>  
            <div className='options'>
                <div className='each_option'>
                    <label htmlFor='any'>Any</label>  
                    <input type='radio' name='dealType' className='any' value='any' />
               </div>
               <div className='each_option'>
                <label htmlFor='sale'>Sale</label>  
                    <input type='radio' name='dealType' className='sale' value='sale' />
                </div>
                <div className='each_option'>
                    <label htmlFor='rent'>Rent</label>  
                    <input type='radio' name='dealType' className='rent' value='rent' />
                </div>
            </div>
        </div>
    </div>
)

export default Filter;

您用于呈现过滤列表 ( Listings ) 的组件是根据以下代码基于 state 呈现的。

constructor(props) {
        super(props);
        this.state = {
            listings: props.ListingsData
        }
    }

安装组件时仅调用一次构造函数。 所以,state 永远不会从最初的 state 修改,即使你传递了新的过滤道具。 为避免这种行为,请使用道具显示列表数据。

因此,您可以更改列表组件以从道具呈现。

class Listings extends React.Component {

    render() {
        const {ListingData:listings} =  this.props;
        if (listings === undefined || listings.length === 0) {
            return <h2>sorry no data found</h2>
        }

        return (
            <div className='listings'>
                {listings.map(({ id, ...props}) => (
                    <div key={id}>
                      {JSON.stringify(props)}
                    </div>
                ))}
            </div>
        )
    }
}

试试下面的 SO 片段。 将下拉列表更改为公寓、别墅、公寓以查看正在呈现的过滤数据。

 const ListingsData = [ { type: "apartment", location: "New york" }, { type: "apartment", location: "New york" }, { type: "apartment", location: "New york" }, { type: "villa", location: "New york" }, { type: "condo", location: "New york" }, { type: "condo", location: "Washington" } ]; let Filter = props => { return ( <div className="filter"> <div className="type"> <label htmlFor="propertyType">Type</label> <select className="propertyType" name="houseType" onChange={props.filterTypeHouse} > <option value="any">Any</option> <option value="family-house">Family House</option> <option value="single-house">Single house</option> <option value="apartment">Apartment</option> <option value="villa">Villa</option> <option value="office-building">Office Building</option> <option value="condo">Condo</option> </select> </div> <div className="location"> <label htmlFor="PropertyLocation">Location</label> <select className="PropertyLocation"> <option>Any</option> <option>New york</option> <option>California</option> <option>Washington</option> <option>philedelphia</option> <option>Boston</option> </select> </div> <div className="min-price"> <label htmlFor="priceFrom">Min-Price</label> <input type="text" className="priceFrom" placeholder="min-price" /> </div> <div className="max-price"> <label htmlFor="priceTo">Max-Price</label> <input type="text" className="priceTo" placeholder="max-price" /> </div> <div className="dealOption"> <label htmlFor="options">Type Of Deal</label> <div className="options"> <div className="each_option"> <label htmlFor="any">Any</label> <input type="radio" name="dealType" className="any" value="any" /> </div> <div className="each_option"> <label htmlFor="sale">Sale</label> <input type="radio" name="dealType" className="sale" value="sale" /> </div> <div className="each_option"> <label htmlFor="rent">Rent</label> <input type="radio" name="dealType" className="rent" value="rent" /> </div> </div> </div> </div> ); } class Listings extends React.Component { render() { const {ListingData:listings} = this.props; if (listings === undefined || listings.length === 0) { return <h2>sorry no data found</h2> } return ( <div className='listings'> {listings.map(({ id, ...props}) => ( <div key={id}> {JSON.stringify(props)} </div> ))} </div> ) } } class Main_content extends React.Component { constructor(props) { super(); this.state = { listingsData: ListingsData, searchOnChange: '', filterdProperties: ListingsData, } } change = (e) => { console.log("Calling change handler"); this.setState({ [e.target.name]: e.target.value }, () => { this.filterData(); } ) } filterData = () => { console.log("Calling filter data"); let newData = this.state.listingsData.filter(property => { return property.type.toLowerCase().toString() === this.state.houseType.toLowerCase().toString() }) this.setState({ filterdProperties: newData }, () => { console.log("State", this.state); }); } render() { return ( <div className="main-content"> <div className="listings-container"> <Listings ListingData={this.state.filterdProperties} /> </div> <div className="filter-sidebar"> <Filter filterTypeHouse={this.change} /> </div> </div> ); } } ReactDOM.render(<Main_content />,document.getElementById("root"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM