You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何从子Input组件获取输入值并更新父组件状态

问题描述

我希望获取“Email Address”和“Password”两个输入框的值,并通过setEmail和setPassword来更新对应的状态,但不知道该如何从子组件的输入框中获取这些值?我移除了onChange事件,当前的硬编码值是用于测试的,但这让我疑惑该如何获取输入值。

父组件代码

import { useState } from "react"
import Input from "./form/Input";
import { useNavigate, useOutletContext } from "react-router-dom";

const Login =() => {

    const [email,setEmail] = useState("");
    const [password,setPassword] = useState("");
    const {setJwtToken} = useOutletContext("");
    const {setAlertClassName} = useOutletContext("");
    const {setAlertMessage} = useOutletContext("");
    const navigate = useNavigate();


    const handleSubmit=(event)=>{

        event.preventDefault();
        console.log("email/password",email,password);

        let payload ={
            email: email,
            password: password,
        }

        const requestOptions = {
            method: "POST",
            headers: {
                'Content-Type':'application/json'
            },
            credentials: 'include',
            body: JSON.stringify(payload)
        }

        fetch(`/authenticate`,requestOptions)
        .then((request)=> request.json())
        .then((data) => {
            if(data.error) {
                setAlertClassName("alert-danger");
                setAlertMessage(data.message);
            } else {
                setJwtToken(data.access_token);
                setAlertClassName("d-none");
                setAlertMessage("");
                navigate("/");

            }
        })
        .catch(error => {
            setAlertClassName("alert-danger");
            setAlertMessage(error);
        })

    }

    return (

        <div className="col-md-6 offset-md-3">
            <h2>Login</h2>
            <hr/>
            <form onSubmit={handleSubmit}>
                <Input
                    title="Email Address"
                    type="email"
                    className="form-control"
                    name="email"
                    autoComplete="email-new"

                    value="admin@example.com"
                />
                <Input
                    title="Password"
                    type="password"
                    className="form-control"
                    name="password"
                    autoComplete="password-new"

                    value="secret"
                />
                <Input
                    type="submit"
                    className="btn btn-primary"
                    value="Login"
                />
            </form>
        </div>

    )
}

export default Login

子组件代码

import { forwardRef } from "react"

const Input = forwardRef((props,ref)=> {
    return(
        <div className="mb-3">
            <label htmlFor={props.name} className="form-lable">
                {props.title}
            </label>
            <input
                type={props.type}
                className={props.className}
                id={props.id}
                ref={ref}
                name={props.name}
                placeholder={props.placeHolder}
                onChange={props.onChange}
                autoComplete={props.autoComplete}
                value={props.value}
            />

            <div className={props.errorDiv}>{props.errorMsg}</div>

        </div>

    )
})

export default Input;

解决方案

你的子组件已经支持接收onChange属性并传递输入框的事件,只需要在父组件中添加状态更新的逻辑即可,下面提供两种常用实现方式:

方式1:独立处理每个输入框的变化

为邮箱和密码分别定义专属的事件处理函数,传递给对应的Input组件:

import { useState } from "react"
import Input from "./form/Input";
import { useNavigate, useOutletContext } from "react-router-dom";

const Login =() => {

    const [email,setEmail] = useState("admin@example.com");
    const [password,setPassword] = useState("secret");
    const {setJwtToken} = useOutletContext("");
    const {setAlertClassName} = useOutletContext("");
    const {setAlertMessage} = useOutletContext("");
    const navigate = useNavigate();

    // 处理邮箱输入变化
    const handleEmailChange = (e) => {
        setEmail(e.target.value);
    }

    // 处理密码输入变化
    const handlePasswordChange = (e) => {
        setPassword(e.target.value);
    }

    const handleSubmit=(event)=>{
        event.preventDefault();
        console.log("email/password",email,password);
        // 原有提交逻辑保持不变
    }

    return (
        <div className="col-md-6 offset-md-3">
            <h2>Login</h2>
            <hr/>
            <form onSubmit={handleSubmit}>
                <Input
                    title="Email Address"
                    type="email"
                    className="form-control"
                    name="email"
                    autoComplete="email-new"
                    value={email}
                    onChange={handleEmailChange}
                />
                <Input
                    title="Password"
                    type="password"
                    className="form-control"
                    name="password"
                    autoComplete="password-new"
                    value={password}
                    onChange={handlePasswordChange}
                />
                <Input
                    type="submit"
                    className="btn btn-primary"
                    value="Login"
                />
            </form>
        </div>
    )
}

export default Login

方式2:通用处理函数(适用于多字段表单)

用一个对象管理所有表单状态,通过输入框的name属性匹配对应的状态字段,减少重复代码:

import { useState } from "react"
import Input from "./form/Input";
import { useNavigate, useOutletContext } from "react-router-dom";

const Login =() => {

    const [formData, setFormData] = useState({
        email: "admin@example.com",
        password: "secret"
    });
    const {setJwtToken} = useOutletContext("");
    const {setAlertClassName} = useOutletContext("");
    const {setAlertMessage} = useOutletContext("");
    const navigate = useNavigate();

    // 通用输入变化处理函数
    const handleInputChange = (e) => {
        const { name, value } = e.target;
        setFormData(prev => ({
            ...prev,
            [name]: value
        }));
    }

    const handleSubmit=(event)=>{
        event.preventDefault();
        const { email, password } = formData;
        console.log("email/password",email,password);
        // 提交时直接使用formData作为payload即可
        let payload = formData;
        // 原有提交逻辑保持不变
    }

    return (
        <div className="col-md-6 offset-md-3">
            <h2>Login</h2>
            <hr/>
            <form onSubmit={handleSubmit}>
                <Input
                    title="Email Address"
                    type="email"
                    className="form-control"
                    name="email"
                    autoComplete="email-new"
                    value={formData.email}
                    onChange={handleInputChange}
                />
                <Input
                    title="Password"
                    type="password"
                    className="form-control"
                    name="password"
                    autoComplete="password-new"
                    value={formData.password}
                    onChange={handleInputChange}
                />
                <Input
                    type="submit"
                    className="btn btn-primary"
                    value="Login"
                />
            </form>
        </div>
    )
}

export default Login

注意事项

  • 必须将输入框的value绑定到父组件的状态值,这样输入框会和状态双向同步,输入内容时状态会实时更新。
  • 子组件无需修改,它已经实现了将输入框的onChange事件传递给父组件的逻辑。

内容的提问来源于stack exchange,提问作者user63898

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 09:05:59