[英]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.