如何在reactjs-output[object]中的函数组件之间传递值?

ztyzrc3y  于 2021-07-14  发布在  Java
关注(0)|答案(1)|浏览(285)

我最近学习了如何在位于不同.js文件中的功能组件中传递道具。现在我在传递同一个.js文件中的函数组件时遇到了问题。
我想得到 member_id 从我的第一个函数中的get请求 GetMemID 用它来设定 member_id 在我的第二个函数中的使用状态 Transactions .
我知道我的get请求正在工作,因为我可以在检查代码后看到数据。
到目前为止,我的代码是“[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;
vnzz0bqm

vnzz0bqm1#

发行

在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
/>

解决方案 stateitem.member_id 值,因此无需将其打包到对象中。因为父级中的状态是异步更新的,所以您需要对组件更新做出React。使用 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]);

我建议更准确地命名道具,即命名道具 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]);

相关问题