【问题标题】:How to pass data from functional component to class component如何将数据从功能组件传递到类组件
【发布时间】:2020-06-01 05:56:34
【问题描述】:

我是 ReactJS 的新手,并且已经为用户输入数据(日期和选择)创建了一个功能组件。 另一个从用户输入数据调用 API 的类组件。我需要将输入值从功能组件传递到类组件。

你能帮忙吗?

下面是带有输入字段的功能组件的 sn-p。 setShowGetAPI 最初设置为 false,一旦用户单击提交按钮,它将为 true。请让我知道条件是否正确

  const [showTable, setshowTable] = useState("hidetable");
const [showGetAPI, setShowGetAPI] = React.useState("false");  


  const [startDate, setStartDate] = useState(false);
  const [endDate, setendDate] = useState(false);
  const [expenseType, setexpenseType] = useState(false);


const showMessage = () => {
    setshowTable("");
    setShowGetAPI("true");
  };

  debugger;
  const handleEndDate = (e) => {
    setendDate(e.target.value);
  };

  const handleStartDate = (e) => {
    setStartDate(e.target.value);
  };

  const handleType = (e) => {
    console.log(e.target.value);
    setexpenseType(e.target.value);
  };
  console.log(endDate);

  return (
    <div>
      <Navbar color="info" light expand="md">
        <Nav color="info" navbar>
          <NavItem className="hdr">
            <NavLink>API Demo Tool</NavLink>
          </NavItem>
        </Nav>
      </Navbar>
      <Nav tabs>
        <NavItem>
          <NavLink
            className={{ active: activeTab === "1" }}
            onClick={() => {
              toggle("1");
            }}
          >
            Request
          </NavLink>
        </NavItem>
        <NavItem>
          <NavLink
            className={{ active: activeTab === "2" }}
            onClick={() => {
              toggle("2");
            }}
          >
            Receipt
          </NavLink>
        </NavItem>
      </Nav>
      <TabContent activeTab={activeTab}>

        <TabPane tabId="2">
          <br />
          <Form>
            <FormGroup row>
              <Label for="Start Date" sm={1}>
                Start Date
              </Label>
              <Col sm={2}>
                <Input
                  type="date"
                  name="startDate"
                  id="startDate"
                  placeholder="startDate"
                  value={startDate}
                  onChange={handleStartDate}
                />
              </Col>
            </FormGroup>
            <FormGroup row>
              <Label for="End Date" sm={1}>
                End Date
              </Label>
              <Col sm={2}>
                <Input
                  type="date"
                  name="endDate"
                  id="endDate"
                  value={endDate}
                  placeholder="endDate"
                  onChange={handleEndDate}
                />
              </Col>
            </FormGroup>
            <FormGroup row>
              <Label for="Segment" sm={1}>
                Expense Type
              </Label>
              <Col sm={2}>
                <Input
                  type="select"
                  name="expenseType"
                  value={expenseType}
                  id=" expenseType"
                  onChange={handleType}
                >
                  <option>Hotel</option>
                  <option>Airfare</option>
                  <option>Rail</option>
                  <option>All</option>
                </Input>
              </Col>
            </FormGroup>
            <FormGroup check row>
              <Col sm={{ size: 10, offset: 1 }}>
                <Button onClick={showMessage}>Submit</Button>
              </Col>
            </FormGroup>
          </Form>
          <div>

            {showGetAPI == "true" && (
            <div>
              <GetAPI
                startDt={startDate}
                endDt={endDate}
                exptype={expenseType}
              />
            </div>
          )}
          </div>
          <div class={showTable}>
            <Table></Table>
          </div>
        </TabPane>
      </TabContent>
    </div>
  );
};

export default TabsDemo;

GETAPI- 这是一个类组件,我需要来自上述功能组件的输入值来调用带有 req 的 API。参数

class GetAPI extends Component {
  constructor(props) {
    super(props);
    this.state = {
      ID: [],
      ReportEntryID: [],
      token: null,
      Url: [
        {
          Url: "",
        },
      ],
    };
  }

  componentDidMount() {

    console.log(this.props.exptype);
    var accesstoken;
    let reports = [];

    axios
      .post(API, qs.stringify(requestBody), config)
      .then((result) => {
        console.log(result);
        this.setState({ token: result.data.access_token });
        accesstoken = result.data.access_token;
        console.log("access token ins " + accesstoken);
        invokeGetReport(accesstoken);
      })
      .catch((error) => {
        console.log(error);
        console.log(error.data);
      });

    function invokeGetReport(accesstoken) {
      console.log("access token is " + accesstoken);
      const config_req = {
        headers: {
          Accept: "application/json",
          Authorization: "Bearer " + accesstoken,
        },
      };

      axios
        .get(test_report_url, config_req)
        .then((resp) => {
          console.log(resp);
          console.log("data id is " + resp.data.Items.length);

          //  debugger;
          for (let i = 0; i < resp.data.Items.length; i++) {
            let reportName = resp.data.Items[i].Name;
            let reportID = resp.data.Items[i].ID;
            console.log("id is : " + reportID + "Report Name : " + reportName);
            invokeGetReportDetails(accesstoken, reportID);
            reports.push(reportID);
          }
          //  invokeGetReportDetails(accesstoken, reports);
        })
        .catch((error) => {
          console.log(error);
          console.log(error.data);
        });
    }

    function invokeGetReportDetails(accesstoken, reportID) {
      console.log("reportID in detail API is " + reportID);
      const config_req = {
        headers: {
          Accept: "application/json",
          Authorization: "Bearer " + accesstoken,
        },
      };

      axios
        .get(report_details + reportID, config_req)
        .then((resp) => {
          console.log(resp);
          console.log(
            "report data id is " + resp.data.ExpenseEntriesList.length
          );
          for (let i = 0; i < resp.data.ExpenseEntriesList.length; i++) {
            let expenseEntryId = resp.data.ExpenseEntriesList[i].ReportEntryID;
            let ExpenseTypeName =
              resp.data.ExpenseEntriesList[i].ExpenseTypeName;
            console.log(
              "id is : " +
                expenseEntryId +
                " ExpenseTypeName : " +
                ExpenseTypeName
            );
            invokeImageURL(accesstoken, expenseEntryId);
          }
        })
        .catch((error) => {
          console.log(error);
          console.log(error.data);
        });
    }

    function invokeImageURL(accesstoken, expenseEntryId) {
      console.log("expenseEntryId in detail API is " + expenseEntryId);

      const config_req = {
        headers: {
          Accept: "application/json",
          Authorization: "Bearer " + accesstoken,
        },
      };

      axios
        .get(image_url + expenseEntryId, config_req)
        .then((resp) => {
          console.log(resp);
          console.log("URL is " + resp.data.Url);
          this.setState({ Url: resp.data.Url });
        })
        .catch((error) => {
          console.log(error);
          console.log(error.data);
        });
    }

    console.log("repoddrts sdda " + reports[1]);
    console.log("prop value is " + this.props);
    // console.log("report id " + this.state.ID);
  }

  render() {
    return <h1> {this.props.startdate}</h1>;
  }
}

export default GetAPI;

【问题讨论】:

  • 您遇到什么类型的问题?
  • 当我打印道具值时,它会显示为空白
  • showMessage 的作用是什么? GetApi 组件在初始渲染时被调用,当时所有的道具都设置为 false。在安装 GetApi 组件时使用一些条件,例如在表单提交时将设置为 true 的使用状态。
  • Rohit - showMessage 函数用于在用户点击提交后调用GetAPI组件,值设置为true

标签: reactjs react-router


【解决方案1】:

您的 getApi 组件安装在您的父组件的第一次渲染上。 因此,您必须像这样在 getApi 组件中检查是否使用 componentDidUpdate。

在您的 getApi 组件中

componentDidUpdate = (prevProps) => {  
  console.log('prevProps',prevProps);
  console.log('this props',this.props);
}

检查您是否获得道具? 希望这会有所帮助。

【讨论】:

  • @ammy 这确实是您的问题,而不是请按照标记进行操作,可以关闭 que。
  • 你能告诉我如何防止getAPI组件在上面代码中没有提交按钮的情况下调用吗?
  • const [showGetAPI, setShowGetAPI] = useState(false); 并在布尔值中更新true,而不是像“true”这样的字符串,并且像{showGetAPI &amp;&amp; &lt;div&gt; &lt;GetAPI startDt={startDate} endDt={endDate} exptype={expenseType} /&gt; &lt;/div&gt; }一样做
  • 谢谢,它有效.. 当我在 this.setState({ Url: resp.data.Url }); 收到错误时,我有一个查询在 GETAPI TypeError: Cannot read property 'setState' of undefined.. 请建议.. 我的用例是将所有 URL 存储在 state 中并将其传递给下一个组件
  • 完成,感谢您的帮助,我有最后一个问题 - 我在 this.setState({ Url: resp.data.Url });在 GETAPI TypeError: Cannot read property 'setState' of undefined.. 请建议.. 我的用例是将所有 URL 存储在 state 中并将其传递给下一个组件
【解决方案2】:

您正在通过 props 从类组件中的功能组件传递数据。因此,您应该能够访问 GetAPI 类组件中的数据,例如:

this.props.startDt
this.props.endDt
this.props.exptype

在您的 GetApi 函数中,您正在渲染:

render() {
    return <h1> {this.props.startdate}</h1>;
}

相反,您传递的是startDt,所以您应该这样做:

render() {
    return <h1> {this.props.startDt}</h1>;
}

【讨论】:

  • 当我打印它的值时,它是空白的。我添加了仅在单击提交按钮时才调用 GetAPI 的条件,但在没有单击按钮的情况下调用它 {showGetAPI == "true" && (
    )}
  • 你能在上面的问题中更新你的代码sn-ps吗?这样会更清楚。
  • 当我在 this.setState({ Url: resp.data.Url }); 收到错误时,我有一个查询TypeError:无法读取未定义的属性“setState”。请提出建议。我的用例是将所有 URL 存储在 state 中并将其传递给下一个组件。
  • @ammy 这个错误是因为在包含`this.setState({ Url: resp.data.Url });` 的函数中的this 不是指封闭组件。要么绑定this,要么使用箭头函数
  • @Yousaf 你能帮我修改绑定代码吗,我是新手
猜你喜欢
  • 1970-01-01
  • 2021-01-08
  • 2019-11-09
  • 2020-09-11
  • 2021-07-18
  • 1970-01-01
  • 2021-01-26
  • 2019-08-20
  • 2020-02-09
相关资源
最近更新 更多