显示另一个组件中的数据

问题描述 投票:0回答:1

我现在正在学习反应,我正试图让两个组件相互交互。层次结构如下:

  • 应用 --SearchForm --results

有一个数据对象将通过我在SearchForm组件中输入的字符串进行过滤。筛选结果应显示在“结果”组件中。我的逻辑是拥有App组件中所需的所有功能,并将数据传递给各个组件。

我希望能够在结果组件中显示过滤后的数据。有人可以帮我这个吗?

请在下面找到App.js文件的代码,以及我正在使用的对象示例。

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"
        }
    }
]
reactjs
1个回答
1
投票

这实际上是React中的一个简单逻辑。您想在Results组件中显示过滤结果,然后将过滤后的状态传递给它。您可以使用按钮触发搜索,然后可能适合的地方可能是Search组件。为此,您将通过filterData方法将其作为道具传递给您。

我在评论中说了几次“这是一个数组不是对象”,因为你在问题中显示的最后一个数据是对象为粗体,但它是一个数组:)所以,我感到困惑,但你做得对。

您应该使用对象中的prop来过滤数据。正如你想的那样,像user.namecar.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>
© www.soinside.com 2019 - 2024. All rights reserved.