如何在 ReactJS 中的功能组件之间传递值 - 输出 [object Object]/undefined?
Posted
技术标签:
【中文标题】如何在 ReactJS 中的功能组件之间传递值 - 输出 [object Object]/undefined?【英文标题】:How to pass values between functional components in ReactJS- output [object Object]/undefined? 【发布时间】:2021-08-02 10:22:36 【问题描述】:我无法在同一个 .js 文件中的功能组件中传递道具。我之前尝试过发布此问题,但没有任何帮助。
我想在我的第一个函数 GetMemID
中从 GET 请求中获取 member_id
,并使用它在我的第二个函数 Transactions
中设置我的 useState 的 member_id
。
我知道我的 GET 请求正在运行,因为我能够在检查我的代码后看到数据。
到目前为止,使用我的代码,当我在 Transactions
中显示 member_id
时,我得到了“[object Object]”。
这是我目前的代码:
import React, useEffect, useState from 'react';
import Redirect from 'react-router-dom';
import moment from 'moment';
import HomeNavBar from '../components/HomeNavBar.js';
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)
//props.state
const [error, setError] = useState(null);
const [trans, setTrans] = useState(member_id:member_id, category:'', description:'', amount:0);
const [details, setDetails] = useState(id:0, mmeber_id:0, group:"", username:"");
console.log("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://########/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">
<HomeNavBar />
<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">
Select Category
</label>
</div>
<div className="form-group row">
<label className="col-md-12">
<select value=trans.category onChange=e => setTrans( ...trans, category: e.target.value ) >
<option value=""></option>
<option value="billsutilities">Bills/Utilities</option>
<option value="groceries">Groceries</option>
<option value="health">Health</option>
<option value="transportation">Transportation</option>
<option value="ehoppingentertainment">Shopping/Entertainment</option>
<option value="mics.">Mics.</option>
</select>
</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;
【问题讨论】:
API 中的数据结构如何? 在<Transaction member_id=item.member_id />
之前记录item
的值
console.log("member_id: " + member_id);
function Transaction(member_id)
下面的第四行在控制台中显示什么?
@kayuapi_my,它显示“member_id: undefined”
@WebbH,格式为 JSON。
【参考方案1】:
const [isLoading,setIsLoading] = useState(false)
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);
setIsLoading(true);
);
);
, []);
return (
<div className="App">
isLoading && details.map(item => (
<Transaction member_id=item.member_id />
))
</div>
可能的解决方案是 -> 1 ) 因为我在上面的代码示例中使用了 isLoading 状态,它最初是 false 并在从 API 加载数据时设置为 true。并有条件地渲染 Transaction 组件。 2)为了更清楚地调试它,记录状态详细信息的值(以确保我们正确获取数据),类似这样 ->
useEffect(()=>
console.log(details);
,[details])
-
还要检查所有来自 API 的 JSON 数据的键是否正确。
如果对您有用,请分享您的评论。干杯!
【讨论】:
【参考方案2】:问题
将传递的道具存储到本地状态是 React 中的反模式。您遇到的问题是Transaction
已安装并呈现之前 GetMemID
中的 GET 请求解析并更新 details
状态。
解决方案 1
只需在Transaction
组件中直接使用传递的member_id
属性即可。 trans.member_id
只使用一次并且从未更新,因此它处于状态是没有意义的。
const [trans, setTrans] = useState( category:'', description:'', amount:0 );
...
<input type="text" name="member_id" defaultValue=member_id readOnly/>
解决方案 2
如果您真的绝对必须将member_id
存储到状态中,那么您需要使用依赖于道具值的useEffect
挂钩来更新状态。当传递的member_id
属性值更新时,效果回调将更新trans.member_id
。
const [trans, setTrans] = useState(
member_id,
category:'',
description:'',
amount:0,
);
useEffect(() =>
setTrans(trans => (
...trans,
member_id
));
, [member_id]);
注意:这两种解决方案都假定您正确地获取和更新父组件中的details
状态。
【讨论】:
以上是关于如何在 ReactJS 中的功能组件之间传递值 - 输出 [object Object]/undefined?的主要内容,如果未能解决你的问题,请参考以下文章
如何将从数据库接收到的数据作为道具传递给 Reactjs 中的另一个组件
如何从 Reactjs 中的 useEffect 挂钩访问道具