【问题标题】:How to Pass React form state from app to multiple components (functional)如何将 React 表单状态从应用程序传递给多个组件(功能性)
【发布时间】:2020-10-06 22:04:12
【问题描述】:

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

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

在我画得很糟糕的图片中,我显然有这个应用程序,还有一个预算主页来管理它的孩子的状态。我想我应该这样做,因为这是我知道的唯一方法。 我遇到的问题是:我不知道如何正确地在整个组件中传递状态。二:我什至不知道我所做的是否正确。 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>
        )}

显然有更多其他页面的导入和组件中传递的更多代码。这只是我处理组件方式的简单介绍

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

再次感谢!

【问题讨论】:

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


    【解决方案1】:

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

    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;
        }        
    }
    

    【讨论】:

    • 我当然可以,而且 React Forms 的文档是在基于类的组件中,但是因为我很固执,所以我想知道如何使用函数组件来做到这一点。
    • @Jordan 啊我明白了。我将编辑我的答案,解释如何这样做。
    【解决方案2】:

    您遇到了哪种问题?我假设您留下的代码部分位于组件主体内(一个函数,因为您使用的是函数式方式)。

    即使您必须牢记其他方法,将多个道具传递给子组件也应该没有问题(道具数量过多意味着通常有问题......)

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

    编辑:

    假设您有 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
    }
    

    通常最好直接在 param 中解构你的 props 变量,而不是像这样总是做props.someProp 等:

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

    更多关于解构的信息here

    【讨论】:

    • 我认为我遇到的问题是由于我不完全了解如何在功能组件中传递状态。在预算文件中,我知道我需要创建将通过其子组件使用的状态。但是,我不太了解子组件如何接收状态。另外,我在 vscode 上的调试器无法正常工作,所以很难弄清楚哪里出了问题。我希望这是有道理的。
    • 哦!子组件接收道具作为该功能组件的参数中的对象属性。更新了我的回复
    • 谢谢!出于好奇,如果我在父组件中将对象传递给 useState,这是否意味着(对于您的示例 const ResultPage)我需要将道具作为对象传递?还是道具只是照顾它? const ResultsPage = ({someProp, someOtherProp}) => { ... } OR const ResultsPage = (props) => { ... } React 知道这些 props 正在接收一个对象吗?
    • 你可以传递你想要的任何变量作为道具,所有这些都在你的子组件的props变量中接收。您可以console.log(props 看到它是一个对象,其键是您传递的道具,值是您传递给这些键的变量。如果合适,请将答案标记为正确
    猜你喜欢
    • 1970-01-01
    • 2017-11-17
    • 2016-10-15
    • 2021-11-13
    • 2023-03-21
    • 2017-11-07
    • 2016-12-05
    • 2018-01-15
    • 2017-01-26
    相关资源
    最近更新 更多