繁体   English   中英

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

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

我是反应的初学者。 我正在开发一个可以从 API 呈现表格数据的项目,用户应该能够根据复选框形式的选择来过滤表格。 我在 2 个不同的组件中有 forms(复选框)。

我试图弄清楚处理来自任一组件的用户输入并显示在不同组件中呈现的过滤数据的正确方法是什么。

我有一个组件在从 API 获取数据后呈现“数据表”。

表格组件:

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

我有 2 个不同的组件来处理用户输入。

带有复选框的组件 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

带有其他过滤器选项的组件 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

如果有人可以帮助我找出一种有效的方法,通过使用位于不同不相关组件中的过滤器来过滤和显示“表格组件”上存在的数据,那就太好了。

提前致谢。

我可以想出 3 种方法来解决这个问题。

  1. TissueOptions中的数据提升到同时存在SidebarOptionsSampleList的更高组件。 看起来像这样。
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. 如果您认为数据将用于更多其他组件,您可以考虑实施react-reduxRedux-saga 将需要更多的学习曲线和教程来观看,但它应该会有所帮助。

  2. 您还可以从反应中检查Context API链接)以处理这些。

不会添加最后两个的示例,因为这些是您应该研究如何实现它的东西。

暂无
暂无

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

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