如何在 ReactJS-输出 [object Object] 中的功能组件之间传递值?

Posted

技术标签:

【中文标题】如何在 ReactJS-输出 [object Object] 中的功能组件之间传递值?【英文标题】:How to pass values between functional components in ReactJS- output [object Object]? 【发布时间】:2021-07-14 06:30:50 【问题描述】:

我最近学习了如何在位于不同 .js 文件中的功能组件中传递道具。现在我无法在同一个 .js 文件中的功能组件中传递道具。

我想在我的第一个函数 GetMemID 中从 GET 请求中获取 member_id,并使用它在我的第二个函数 Transactions 中设置我的 useState 的 member_id

我知道我的 GET 请求正在运行,因为我能够在检查我的代码后看到数据。

到目前为止,我的代码是“[object Object]”。

这是我目前的代码:

import React,  useEffect, useState  from 'react';
import moment from 'moment';
import  SigninNavBar from '../components/SigninNavBar.js';
import BrowserRouter as Router, Switch, Route, Link, Redirect from 'react-router-dom';
import 'bootstrap/dist/css/bootstrap.min.css';

var currentDate = moment().format("MM/DD/YYYY HH:mm:ss");

function GetMemID() 

  const [details, setDetails] = useState([]);  
  const [error, setError] = useState(null);

const options = 
  method: 'GET',
  headers: 
    'Content-type': 'application/json; charset=UTF-8',
    'Accept': 'application/json',
    'Authorization': `JWT $localStorage.getItem('token')`
  
;

useEffect(() => 
  fetch("http://#####/api/members/get/", options)
  .then(response => 
    if (response.status !== 200) 
      console.log(response.status);
      setError(response);
    
    response.json().then(data => 
      setDetails(data);
    );
  );
, []);

  return (
    <div className="App">
      details.map(item => (
         <Transaction member_id=item.member_id />
      ))
    </div>
  );



function Transaction(member_id) 

  
  const [error, setError] = useState(null);
  const [trans, setTrans] = useState(member_id, category:'', description:'', amount:0); 
  const [details, setDetails] = useState(id:0, mmeber_id:0, group:"", username:"");

  //catch any changes made to member_id
  useEffect(() => 
    setTrans(trans => (
      ...trans, 
      member_id,
    ));
  , [member_id]);
  
  //GET rerquest to get transaction memberID
  const options = 
    method: 'GET',
    headers: 
      'Content-type': 'application/json; charset=UTF-8',
      'Accept': 'application/json',
      'Authorization': `JWT $localStorage.getItem('token')`
    ,
  ;
  
  useEffect(() => 
    fetch("http://#####/api/members/get/", options)
    .then(response => 
      if (response.status !== 200) 
        console.log(response.status);
        setError(response);
      
      response.json().then(data => 
        setDetails(data);
      );
    );
  , []);

  //POST request to API for transaction
  const optionPOST = 
    method: 'POST',
    headers: 
      'Content-type': 'application/json; charset=UTF-8',
      'Accept': 'application/json',
      'Authorization': `JWT $localStorage.getItem('token')`
    ,
    body:JSON.stringify(trans)
  

  const createTransaction = e => 
    e.preventDefault();

    fetch("http://34.94.76.5/api/transactions/post/", optionPOST)
    .then((response) => console.log('reponse: ' + response.json()))
    .then((message) => console.log('message: ' + message))
  

  if (error) 
    return (<Redirect to="/Signin" />);
   else
    return (
      <div className="wrapper">
        <SigninNavBar />
        <form>
          <div className="form-horizantal">
            <fieldset>
              <div className="form-group row">
                <label className="col-md-12"><p>currentDate</p></label>
              </div>
              <div className="form-group row">
                <label className="col-md-12">
                  <p>Member ID</p>
                  <input type="text" name="member_id" defaultValue=trans.member_id readOnly/>
                </label>
              </div>

              <div className="form-group row">
                <label className="col-md-12">
                  <p>Category</p>
                  <input type="text" name="category" value=trans.category onChange=e => setTrans( ...trans, category: e.target.value ) />
                  
                </label>
              </div>

              <div className="form-group row">
                <label className="col-md-12">
                  <p>Description</p>
                  <input type="text" name="description" value=trans.description onChange=e => setTrans( ...trans, description: e.target.value ) />
                </label>
              </div>

              <div className="form-group row">
                <label className="col-md-12">
                  <p>Amount</p>
                  <input type="text" name="amount" value=trans.amount onChange=e => setTrans( ...trans, amount: e.target.value ) />
                </label>
              </div>
            </fieldset>

            <button type="submit" onClick=createTransaction>Submit</button>
          </div>
        </form>
      </div>
    );
  


export default Transaction;

【问题讨论】:

你从哪里得到[object Object] 哪里有GetMemID函数?你在哪里'到目前为止,我的代码,我得到了“[object Object]”。'? @DrewReese,很抱歉!我对其进行了编辑以包含该功能。 @JorgeKunrath [object Object] 是这行代码的输出 &lt;input type="text" name="member_id" defaultValue=trans.member_id readOnly/&gt; 【参考方案1】:

问题

您正在渲染一个在 React 中的 JSX 中无效的对象。您正在传递看起来是一个值的东西:

<Transaction state=item.member_id />

但是然后在设置初始状态值的时候把这个打包成Tranaction中的一个对象:

function Transaction( state ) 
  ...
  const [trans, setTrans] = useState(
    member_id:  state , // <-- packed prop value into object
    category:'',
    description:'',
    amount:0,
  );

因此,在渲染输入时,您将对象作为输入的默认值传递:

<input
  type="text"
  name="member_id"
  defaultValue=trans.member_id // <-- object value!!
  readOnly
/>

解决方案

state item.member_id 值,因此无需将其打包到对象中。由于父级中的状态是异步更新的,因此您需要对组件更新做出反应。使用 useEffect 钩子“观察”state 属性的变化。

function Transaction( state ) 
  ...
  const [trans, setTrans] = useState(
    member_id: state, // <-- set as passed prop value
    category:'',
    description:'',
    amount:0,
  );

  useEffect(() => 
    setTrans(trans => (
      ...trans, // <-- copy previous state
      member_id: state, // <-- update member_id from props
    ));
  , [state]);

我建议更准确地命名prop,即命名为member_id,然后设置初始状态会更干净一些。

<Transaction member_id=item.member_id />

...

function Transaction( member_id ) 
  ...
  const [trans, setTrans] = useState(
    member_id, // <-- set as passed prop value via object shorthand notation
    category:'',
    description:'',
    amount:0,
  );

  useEffect(() => 
    setTrans(trans => (
      ...trans, // <-- copy previous state
      member_id, // <-- update member_id from props
    ));
  , [member_id]);

【讨论】:

感谢您的深入解释!我确实明白了很多。但是,在做出您建议的更正后,我仍然没有运气。它摆脱了[object Object] 输出,但现在,我根本没有得到输出。 @KassandraI 哎呀,是的,父级中的状态是异步更新的,因此子级需要实现一个生命周期挂钩来响应对道具的更改(以及必要时的状态)。我已经更新了我的答案,希望可以解决这个问题。 我明白了,我将不得不研究异步状态。我的代码仍然没有显示member_id,但我可以肯定地说我学到了很多关于传递道具的知识。

以上是关于如何在 ReactJS-输出 [object Object] 中的功能组件之间传递值?的主要内容,如果未能解决你的问题,请参考以下文章

PHP如何在没有ob_start()的情况下获得服务器的累积HTML输出[重复]

ReactJs 和 Typescript,使用 TSX 时如何更改对象内变量的状态

如何在 ReactJS 中验证嵌套对象的 PropTypes?

ReactJS 无法构造“WebSocket”:子协议“[object Object]”无效

如何在 ReactJS 中对 HTML 表进行排序

转PHP ob_start() 函数介绍