此刻我正在学习反应,我试图让两个组件相互交互。层次结构如下:
应用
-SearchForm
-结果
有一个数据对象将通过在 SearchForm 组件中输入的字符串进行过滤。过滤后的结果应显示在 Results 组件中。 我的逻辑是拥有App组件所需的所有功能,并将数据传递给各个组件。
我希望能够在结果组件中显示过滤的数据。 有人可以帮我吗?
请在下面找到 App.js 文件的代码,以及我正在使用的对象的示例。
import React, { Component } from "react";
import styled from "styled-components";
import Header from "./Header";
import SearchForm from "./SearchForm";
import Results from "./Results";
import Map from "./Map";
const Outer = styled.div`
text-align:center;
`;
class App extends Component {
constructor(props) {
super(props);
this.state = {
query: "",
data: [],
refinedData: [],
};
// this.handleSearchChange = this.handleSearchChange.bind(this);
}
handleSearchChange = (event) => {
this.setState({
query: event.target.value,
});
}
getData = async () => {
const response = await fetch("http://localhost:4200/bookings");
const json = await response.json();
this.setState({
data: json,
})
console.log(this.state.data);
}
filterData = () => {
const filtered = this.state.data.filter(element => {
return element.toLowerCase().includes(this.state.query.toLowerCase());
});
this.setState({
refinedData: filtered,
});
console.log(this.state.refinedData);
}
componentDidMount() {
this.getData();
}
render() {
return (
<Outer>
<Header/>
<SearchForm triggeredUpdate={this.handleSearchChange}/>
<Results searchQuery={this.state.filterData}/>
<Map/>
</Outer>
);
}
}
export default App;
[
{
"id": 50000,
"car": {
"id": 1000,
"licence_plate": "SKK5050Q"
},
"book_start": 1543271643,
"book_end": 1543340723,
"pickup": {
"id": 87,
"code": "WDL",
"lat": 1.434,
"lng": 103.78
},
"dropoff": {
"id": 85,
"code": "TPY",
"lat": 1.33,
"lng": 103.851
},
"user": {
"id": 51498,
"name": "Count Dooku"
}
}
]
答案 0 :(得分:1)
这实际上是React
中的简单逻辑。您想在Results
组件中显示过滤结果,然后将过滤状态传递给它。您可以使用按钮触发搜索,然后可能合适的位置是Search
组件。为此,您将按照自己的想法将filterData
方法传递给它。
我在评论中说了几次“它是一个数组而不是对象”,因为您在问题中显示的最后一个数据将 Object 表示为粗体,但这是一个数组:)所以,我得到了感到困惑,但您做对了。
您应该在对象中使用道具过滤数据。再想一想,例如user.name
,car.license_late
等。这里需要一个目标。
这是一个简单的工作示例:
class App extends React.Component {
state = {
query: "",
data: [
{
"id": 50000,
"car": {
"id": 1000,
"licence_plate": "SKK5050Q"
},
"book_start": 1543271643,
"book_end": 1543340723,
"pickup": {
"id": 87,
"code": "WDL",
"lat": 1.434,
"lng": 103.78
},
"dropoff": {
"id": 85,
"code": "TPY",
"lat": 1.33,
"lng": 103.851
},
"user": {
"id": 51498,
"name": "Count Dooku"
}
}
],
refinedData: [],
};
handleSearchChange = event => this.setState({
query: event.target.value,
});
filterData = () => {
const { data, query } = this.state;
const filtered = !query ? [] : data.filter(element =>
element.car.licence_plate.toLowerCase().includes(this.state.query.toLowerCase())
);
this.setState({
refinedData: filtered,
});
}
render() {
return (
<div>
<SearchForm filterData={this.filterData} triggeredUpdate={this.handleSearchChange} />
<Results refinedData={this.state.refinedData} />
</div>
);
}
}
const Results = props => (
<div>
{
props.refinedData.map( el =>
<div key={el.id}>
<p>ID: {el.id}</p>
<p>User name: {el.user.name}</p>
</div>
)
}
</div>
)
const SearchForm = props => (
<div>
<input onChange={props.triggeredUpdate} />
<br />
<button onClick={props.filterData}>Search</button>
</div>
)
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
讨论讨论后更新
键入时,您无需按钮即可进行搜索。由于将过滤器逻辑移至filterData
方法中,因此我们不再具有handleSearchChange
方法。另外,我们现在不需要任何query
状态。
filterData
数组。如果没有搜索value
,我们将返回一个空数组,因为如果没有任何搜索,我们不想列出所有数据。顺便说一下,我也据此更新了以前的解决方案。如果我们用空的输入按下Search
按钮,它将返回所有数据。
class App extends React.Component {
state = {
data: [
{
"id": 50000,
"car": {
"id": 1000,
"licence_plate": "SKK5050Q"
},
"book_start": 1543271643,
"book_end": 1543340723,
"pickup": {
"id": 87,
"code": "WDL",
"lat": 1.434,
"lng": 103.78
},
"dropoff": {
"id": 85,
"code": "TPY",
"lat": 1.33,
"lng": 103.851
},
"user": {
"id": 51498,
"name": "Count Dooku"
}
}
],
refinedData: [],
};
handleSearchChange = event => {
const { value: query } = event.target;
this.setState(prevState => {
const filteredData = !query ? [] : prevState.data.filter(element =>
element.car.licence_plate.toLowerCase().includes(query.toLowerCase())
);
return {
refinedData: filteredData
};
});
}
render() {
return (
<div>
<SearchForm triggeredUpdate={this.handleSearchChange} />
<Results refinedData={this.state.refinedData} />
</div>
);
}
}
const Results = props => (
<div>
{
props.refinedData.map(el =>
<div key={el.id}>
<p>ID: {el.id}</p>
<p>User name: {el.user.name}</p>
</div>
)
}
</div>
)
const SearchForm = props => (
<div>
<input onChange={props.triggeredUpdate} />
</div>
)
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>