简体   繁体   English

State 未在从子级到父级的处理程序调用上更新

[英]State isn't updated on handler call from child to parent

I have a parent component PlannerDetails and a child component PlannerDetailsFooter .我有一个父组件PlannerDetails和一个子组件PlannerDetailsFooter Now when I click the button {props.emailConfig.buttonText} doesn't update with string Send Now , the boolean does though.现在,当我单击按钮时{props.emailConfig.buttonText}不会更新为字符串Send Now ,但 boolean 会更新。

// PlannerDetails

import {useState} from "react";
import PlannerDetailsHead from "./PlannerDetailsHead";
import PlannerDetailsBody from "./PlannerDetailsBody";
import PlannerDetailsFooter from "./PlannerDetailsFooter";

const PlannerDetails = (props) => {

    const [emailConfig, setEmailConfig] = useState(
        {
            'email': '',
            'isSent': false,
            'isHidden': true,
            'buttonText': 'Send via Email'
        }
    )

    const emailHandler = (event) => {
        if (event.id === "mail-button") {
            setEmailConfig({...emailConfig, isHidden: false})
            setEmailConfig({...emailConfig, buttonText: 'Send Now'})
        } else {
            setEmailConfig(event.target.value)
        }
    }

    return (
        <div className="details-wrapper relative h-full">
            <PlannerDetailsHead {...props}/>
            <PlannerDetailsBody {...props}/>
            <PlannerDetailsFooter {...props} emailConfig={emailConfig} emailHandler={emailHandler}/>
        </div>
    )
}

export default PlannerDetails
// PlannerDetailsFooter

import {TextField} from "@mui/material";

const PlannerDetailsFooter = (props) => {
    return (
        <div className="details-footer w-full p-4 bottom-0 absolute border-t-1">
            {props.emailConfig.isHidden ? null :
            <TextField
                id="email-input"
                label="Applicant's E-Mail"
                variant="outlined"
                required={true}
                sx={{
                    width: '200px',
                    marginRight: '12px',
                }}
                value={props.emailConfig.email}
                onChange={props.emailHandler}
            />}
            <button id="mail-button"
                    className="send-mail p-2 bg-sx-pink rounded-md shadow-lg text-sx-purple-dark-soft"
                    onClick={props.emailHandler}
            >{props.emailConfig.buttonText}</button>
        </div>
    )
}

First you'll want to debug to confirm whether this condition is true or not:首先,您需要调试以确认此条件是否成立:

if (event.id === "mail-button")

Because if it's not then it looks like this is going to clobber your state object entirely:因为如果不是,那么看起来这将完全破坏您的 state object:

setEmailConfig(event.target.value)

So it's not really clear at all what state update you want to make in that else block.因此,您根本不清楚您想在else块中进行什么 state 更新。 It should probably look like your other state updates, at least structurally:应该看起来像您的其他 state 更新,至少在结构上是这样:

setEmailConfig({...emailConfig, someProp: 'some value'})

But aside from that, this is incorrect:但除此之外,这是不正确的:

setEmailConfig({...emailConfig, isHidden: false})
setEmailConfig({...emailConfig, buttonText: 'Send Now'})

Only one of these will be applied, because they're both updating different things and state updates are batched and processed asynchronously.只会应用其中一个,因为它们都在更新不同的内容,并且 state 更新是异步批处理和处理的。 So whichever one of these occurs second will overwrite the changes made by the first one.因此,无论其中哪一个发生在第二个,都会覆盖第一个所做的更改。 (They will probably be executed in order, but I don't know if React guarantees that. And in any even, you shouldn't rely on that.) (它们可能会按顺序执行,但我不知道 React 是否保证这一点。无论如何,你不应该依赖它。)

Just perform one state update here:只需在这里执行一次state 更新:

setEmailConfig({...emailConfig, isHidden: false, buttonText: 'Send Now'})

You can perform multiple state updates, making use of the previous updates in the same batch by supplying a callback.可以执行多个 state 更新,通过提供回调在同一批次中使用以前的更新。 For example:例如:

setEmailConfig(prev => {...prev, isHidden: false});
setEmailConfig(prev => {...prev, buttonText: 'Send Now'});

But in this case that's kind of overkill.但在这种情况下,这有点矫枉过正。 You'd use that in more complex logic where it's possible that you might have multiple separate things to update.你会在更复杂的逻辑中使用它,在这种情况下你可能有多个单独的东西要更新。 But honestly in the majority of cases all you want to do is define the new state and call the setter with that new state, so one state update.但老实说,在大多数情况下,您要做的就是定义新的 state 并使用新的 state 调用 setter,这样一个 state 更新。

There is a mistake in your handler function.您的处理程序 function 中存在错误。

1. Especially, this is incore: setEmailConfig(event.target.value) 1. 特别是,这是核心: setEmailConfig(event.target.value)

Because emailConfig is an object, but you are trying to set string value.因为emailConfig是一个 object,但您正在尝试设置string值。

2. Please use setState function with previous state . 2. 请使用setState function 和之前state

Could you try as follows?你可以尝试如下吗?

const emailHandler = (event) => {
    if (event.id === "mail-button") {
      setEmailConfig(prev=> ({
        ...prev,
        isHidden: false,
        buttonText: 'Send Now'
      }))
    } else {
      setEmailConfig(prev=> ({
        ...prev,
        email: event.target.value
      }))
    }
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 尝试从子级更改父级 state 时,父级 State 未更新。 (将处理程序作为道具从父母传递给孩子) - Parent State is not being updated when trying to change the parent state from child. (passing a handler as prop from parent to child) 反应:在父 state 更新后,子 State 没有更新 - React: Child State isn't updating after Parent state gets Updated 为什么即使使用钩子更新父 state 也不重新渲染子组件 - Why isn't child component re-rendered even though parent state is updated using hooks 将更新的 state 从父母传递给孩子 - Passing updated state from parent to child 在onChange事件期间,更新状态并从子组件中同时调用父onChange处理程序 - Update state and call parent onChange handler simultaneously from child component during onChange event 子 state 未使用 react-sliding-pane 更新 - Child state isn't updated with react-sliding-pane ReactJS从子状态onClick处理程序设置父状态 - ReactJS setting parent state from child state onClick handler 子组件的事件处理程序设置状态不会重新呈现父组件 - Event-handler setting state from a child component doesn't re-render parent component 为什么我看不到子组件事件处理程序的父状态? - Why can't I see parent state from child component event handler? 当父 state 更新时,子道具不会 - When parent state is updated child props won't
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM