显示一个组件中另一个组件的数据

时间:2018-08-30 04:04:45

标签: reactjs

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

  • 应用

    -SearchForm

    -结果

有一个数据对象将通过在 SearchForm 组件中输入的字符串进行过滤。过滤后的结果应显示在 Results 组件中。 我的逻辑是拥有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"
        }
    }
]

1 个答案:

答案 0 :(得分:1)

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

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

您应该在对象中使用道具过滤数据。再想一想,例如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>