如何将React表单状态从应用传递到多个组件(功能)

时间:2020-10-06 22:04:12

标签: javascript reactjs forms react-hooks use-state

我对React还是很陌生,所以如果这是重复的帖子,我感到抱歉。我正在与React一起创建一个分布在不同页面上的表单。想法是让您具有从求职申请中收到的表格的类型。一个有多个步骤。

我为表格的每个步骤制作了不同的组件。第一页是主页。想象有一个按钮将您带到创建页面。然后,您会看到创建页面。有一个带有金额名称的小表格。当您单击下一页时,您会看到自定义页面。您可以在此处按优先级编辑预算。

enter image description here

在我画得不好的图片中,我显然拥有该应用程序,并且有一个预算主页来管理孩子的状态。我认为我应该这样做,因为,这是我知道的唯一方法。 我遇到的问题之一是:我不知道如何在整个组件中正确传递状态。第二:我什至不知道我在做什么是否正确。 React文档在基于类的组件中使用表单,这有帮助,但是我无法将其配置为我的问题。

任何帮助或建议,我们将不胜感激。另外,我想显示“预算”页面上的代码。

import React, { useState, useEffect, useRef } from "react";
import BudgetResultsPage from './BudgetResultsPage';

const [count, setState] = useState(0);
const handleStateCount = () => {
        if(count>3) {count = 0;}
        return setState(count + 1);
    }
if(count === 0) {
        console.log(`homepage state ${count}`)
        return (
            <div className={Styles.Calculator}>
                <BudgetHomePage setState={count} handleStateCount={handleStateCount}/>
            </div>
        )
    } else if(count===1) {
        console.log(`budget create state ${count}`)
        return (
            <div className={Styles.Calculator}>
                <CalculatorHeader />
                <CreateBudget setState={count} handleStateCount={handleStateCount} setAmount={amount} handleAmount={handleAmount}/>
            </div>
        )}

显然,其他页面的导入更多,并且组件中传递了更多代码。这只是我处理组件的方式的一小段

这可能很愚蠢,但是我正在创建状态计数,然后在提交表单的一部分时,计数上升,并且根据计数所在的内容更改页面。仅适用于一种状态,但是我在向其添加更多状态时遇到问题。

再次感谢!

2 个答案:

答案 0 :(得分:1)

我已经写了一个示例功能组件来说明您的一些问题。我在家里写的,只有notepad ++,所以如果您复制粘贴,可能无法编译。评论将解释您的问题

import React from 'react';
import Create_budget_page from './Create_budget_page.js';


const BudgetPage = props => {

    // State 1: assigning one value to the state.
    // State 2: assinging a list to the state.
    // State 3: assinging a object to the state.
    const [simple_state, set_simple_state] = useState(false);
    const [list_state, set_list_state] = useState(["Hello","World","!"]);
    const [object_state, set_object_state] = useState(
        {
            curmenu: "human_bios",
            height: "196cm", 
            weight: "174lbs", 
            eye_colour: "blue", 
            hair_colour: "dirty_blonde"
        }
    );
    // there are several possiblities, here's one with a list of objects
    const [list_objects, set_list_objects] = useState(
        [
            {count: 69, wasClicked: false},
            {count: 420, wasClicked: true},
            // endless possibilities, the tricky part is properly correctly updating your states deep in the list
            {integers: [1,5,2,3], keys: {isAlive: false, cur_menu: "config_menu"}}
        ]
    );

    // this function updates the state that stores an object
    // arguments:
    //      new_values_object: the programmer passes in a object to the function with the values they want to update
    //      an example of calling this function in a child functional component:
    //          props.update_object_state({height: "165cm", weight: "143lbs", hair_colour: "black"});
    function update_object_state(new_values_object){
        set_object_state(prevState => {
            const new_obj = prevState;
            // loop through object keys and update the new_obj with the object passed in as a argument
            for (var key in new_values_object){
                new_obj[key] = new_values_object[key];
            }
            // returning the new_object will update the object_state
            return new_obj;
        })
    }



    // conditionally render based on state
    
    switch(object_state["curmenu"]){
        case "home_page":
             return (
                // pass in 
                // all props, 1 prop, state
                <Create_budget_page  {...props}  parent_id={prop.parent_id} simple_state={simple_state} list_objects={list_objects}/>
             ) ;
             break;
        // pass in function
        case "human_bios":
            return (
                <div className="error_page" onClick={() => {props.update_parent_state({error_occured: true})}}>This is an Error Page, click me to report diagnostics</div>
            );
        break;
        // if none of cases are met default code executes
        default:
            // renders nothing 
            return null;
    }        
}

答案 1 :(得分:0)

您遇到哪种问题?我假设您剩下的代码部分位于组件主体(一个函数,就像您使用函数式方法一样)内。

即使您必须牢记其他方法(将过多的道具表示总有问题……),您也可以毫无疑问地将多个道具传递给子组件。

如果您还有其他问题,请告诉我。

编辑:

假设您拥有ResultsPage子组件,并且在父组件中执行以下操作:

<ResultsPage someProp={someValue} someOtherProp={someOtherValue} />

然后在子组件中,您可以管理以下道具:

const ResultsPage = (props) => {
   // props is an object like this: { someProp: someValue, someOtherProp: someOtherValue}
   ...  // and in the body of the function you can manipulate it however you want
}

通常最好直接在参数中破坏props变量,而不要总是像这样props.someProp进行操作,

const ResultsPage = ({someProp, someOtherProp}) => { ... }

有关解构here

的更多信息