简体   繁体   English

如何根据来自 2 个不同组件的用户输入更新表数据

[英]How to update a table data based on user inputs from 2 different components

I am a beginner in react.我是反应的初学者。 And I am working on a project that can render tabular data from an API, and user should be able to filter the table based on selections in the form of checkboxes.我正在开发一个可以从 API 呈现表格数据的项目,用户应该能够根据复选框形式的选择来过滤表格。 I have forms (checkboxes) in 2 different components.我在 2 个不同的组件中有 forms(复选框)。

I am trying to figure out what is the correct way to handle user inputs from either of the components and show the filtered data which is rendered in a different component.我试图弄清楚处理来自任一组件的用户输入并显示在不同组件中呈现的过滤数据的正确方法是什么。

I have a component that renders a "datatable" after fetching data from an API.我有一个组件在从 API 获取数据后呈现“数据表”。

Table component:表格组件:

import React, { useState, useEffect, useMemo } from "react"
import DataService from "./service"
import { MDBDataTable } from "mdbreact"
import { Row, Col, Card, CardBody, CardTitle, CardSubtitle } from "reactstrap"

const SampleList = props => {
  const [samples, setSamples] = useState([])

  useEffect(() => {
    retrieveSamples()
  }, [])

  const retrieveSamples = () => {
    DataService.sampleList()
      .then(response => {
        setSamples(response.data)
      })
      .catch(e => {
        console.log(e)
      })
  }
  
  const data = {
    columns: [
      {
        label: "Sample",
        field: "sample",
      },
      {
        label: "Group",
        field: "group",
      },
    ],
    rows: samples,
  }

  return (
    <React.Fragment>
      <Row>
        <Col className="col-12 pt-4">
          <Card>
            <CardBody>
              <CardTitle>Samples</CardTitle>
              <CardSubtitle className="mb-3">
                Please apply any filter to view the samples
              </CardSubtitle>

              <MDBDataTable responsive striped bordered data={data} />
            </CardBody>
          </Card>
        </Col>
      </Row>
    </React.Fragment>
  )
}

export default SampleList

and I have 2 different components that handle user inputs.我有 2 个不同的组件来处理用户输入。

Component 1 with checkboxes:带有复选框的组件 1:

import React, { useState } from "react"

const tissue = [
  "Flower",
  "Stem",
  "Shoot",
  "Root",
]
function TissueOptions(props) {
  const [formData, updateFormData] = useState([])

  const handleChange = event => {
    let all_checked = []
    if (event.target.checked) {
      console.log("Checked:" + event.target.value)
      updateFormData({
        ...formData,
        [event.target.id]: event.target.value.trim(),
      })
    } else {
      console.log("unchecked: " + event.target.value.trim())
      let newSelection = {}

      Object.entries(formData).forEach(([key, value]) => {
        if (value !== event.target.value.trim()) {
          newSelection[key] = value
        }
      })
      updateFormData(newSelection)
    }
  }

  const handleSubmit = event => {
    event.preventDefault()
    //  how to filter data from the table component
  }

  return (
    <>
      <form onSubmit={handleSubmit}>
        <ul>
          <p>Tissues</p>
          {tissue.map((name, index) => (
            <div className="form-check mb-3">
              <input
                className="form-check-input"
                type="checkbox"
                value={name.toLowerCase()}
                id={index + name}
                onChange={handleChange}
              />
              <label className="form-check-label" htmlFor={index + name}>
                {name}
              </label>
            </div>
          ))}
        </ul>

        
        <button>Filter</button>
      </form>
    </>
  )
}

export default TissueOptions

Component 2 with other filter options: (this is a child component of a separate unrelated component)带有其他过滤器选项的组件 2:(这是一个单独的不相关组件的子组件)

import React, { useState } from "react"

const genotype = ["Wild type", "Mutant", "Transgenic", "Hybrid", "Other", "ND"]
const treatment = ["Treated", "Untreated", "ND"]

function SidebarOptions(props) {
  const [formData, updateFormData] = useState([])

  const handleChange = event => {
    let all_checked = []
    if (event.target.checked) {
      console.log("Checked:" + event.target.value)
      updateFormData({
        ...formData,
        [event.target.id]: event.target.value.trim(),
      })
    } else {
      console.log("unchecked: " + event.target.value.trim())
      let newSelection = {}
      Object.entries(formData).forEach(([key, value]) => {
        if (value !== event.target.value.trim()) {
          newSelection[key] = value
        }
      })
      updateFormData(newSelection)
    }
  }

  const handleSubmit = event => {
    event.preventDefault()
    //  how to filter data from the table component in combination with "filter component 1"
  }

  return (
    <>
      <form onSubmit={handleSubmit}>


        <ul>
          <p>Genotype</p>
          {genotype.map((name, index) => (
            <div className="form-check mb-3">
              <input
                className="form-check-input"
                type="checkbox"
                value={name.toLowerCase()}
                id={index + name}
                onChange={handleChange}
              />
              <label className="form-check-label" htmlFor={index + name}>
                {name}
              </label>
            </div>
          ))}
        </ul>

        <ul>
          <p>Treatment</p>
          {treatment.map((name, index) => (
            <div className="form-check mb-3">
              <input
                className="form-check-input"
                type="checkbox"
                value={name.toLowerCase()}
                id={index + name}
                onChange={handleChange}
              />
              <label className="form-check-label" htmlFor={index + name}>
                {name}
              </label>
            </div>
          ))}
        </ul>
        <button>Filter</button>
      </form>
    </>
  )
}

export default SidebarOptions

It would be great if someone could help me figure out an efficient way to filter and display data present on the 'table component' by using the filters which reside in different unrelated components.如果有人可以帮助我找出一种有效的方法,通过使用位于不同不相关组件中的过滤器来过滤和显示“表格组件”上存在的数据,那就太好了。

Thanks in advance.提前致谢。

I could think of 3 ways you can approach this.我可以想出 3 种方法来解决这个问题。

  1. Hoist the data from SampleList to a higher component where SidebarOptions and TissueOptions also exist.TissueOptions中的数据提升到同时存在SidebarOptionsSampleList的更高组件。 Which would look like this.看起来像这样。
const [sample, setSample] = useState([])

// Handle loading of data 
useEffect(()=>{},[])

// Filter function
const handleFilter = (*expected params*) => {
  // code to handle filter changes

  setSample(filteredList)
}

return (
  <SampleTableWithFilter>
    <SidebarOptions onSubmit={handleFilter}/>
    <SampleList listData={sample} />
    <TissueOptions onSubmit={handleFilter}/>
  </SampleTableWithFilter>
)
  1. You could look into implementing react-redux or Redux-saga if you think the data will be used in many more other components.如果您认为数据将用于更多其他组件,您可以考虑实施react-reduxRedux-saga Will entail a bit more learning curve and tutorials to watch but it should help.将需要更多的学习曲线和教程来观看,但它应该会有所帮助。

  2. You could also check Context API ( link ) from react to handle these.您还可以从反应中检查Context API链接)以处理这些。

Won't be adding samples of the last two since these are something you should look into as to how you would implement it.不会添加最后两个的示例,因为这些是您应该研究如何实现它的东西。

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

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