簡體   English   中英

在 React 中,最初使用 props 的值設置狀態,然后使用 FormControl 更新 state

[英]In React, initially setState using value from props, and then update state using FormControl

不確定如何將其變成 stackoverflow 中的可重現示例,但我們有以下 React 組件,它創建一個 SVG 圖形,它具有可編輯的 header 文本(可以單擊文本進行編輯並鍵入以編輯文本)利用foreignObjectFormControl

import { FormControl } from 'react-bootstrap';

function OurGraph({ headerText }) {
    const [graphText, setGraphText] = useState(headerText);

    // create editable header
    const ourHeader =
        (<foreignObject width='100%' height='40'>
            <div xmlns='http://www.w3.org/1999/xhtml'>
                <FormControl
                    className='modal-input no-style'
                    type='text'
                    value={graphText}
                    onChange={e => setGraphText(e.target.value)}
                    name='subheader'
                    placeholder=''
                />
            </div>
        </foreignObject>);

    // and return
    return (<svg>{ourHeader}</svg>);
}

我們有這個父組件來更新OurGraph組件的默認headerText

function Parent() {
    const [button, setButton] = useState(true);
    const buttonElement =
        (<button onClick={() => setButton(!button)}>
             CLICK ME
         </button>);

    return (
        {buttonElement}
        <OurGraph headerText={button === true ? 'true text' : 'false text'} />
    )
}

這與預期的工作非常接近......當組件最初呈現時, true text顯示為 SVG 中的文本,很好,當我們單擊文本時,文本是可編輯的,很好!

問題是,當我們單擊CLICK ME按鈕時,它會將OurGraph中的headerText屬性從true text更改為false textOurGraph組件中 SVG 中的文本不會更新為false text ,即使 prop 值成功完成更新為false text

為什么是這樣? 我們如何解決這個問題,以便更改的 prop 值反映在 SVG 表單控件的文本中? 我們認為新的headerText值會導致const [graphText, setGraphText] = useState(headerText); graphText設置一個新值,但是當headerText屬性從true text變為false textgraphText沒有改變。

編輯- 雖然從道具值立即設置狀態()似乎是一種反模式,但我們需要 graphText 作為 state 中的變量,因為它在 FormControl 中更新,我們希望道具值headerText成為默認值graphText 最重要的是,每當headerText發生變化時,我們都希望使用在headerText中傳遞的新屬性值覆蓋FormControlgraphText中設置的任何值。

這是反模式的典型例子。 React 不會重新初始化 state。為了使其正常工作,您可以執行以下操作:

import { FormControl } from 'react-bootstrap';
   import {useEffect} from 'react';

   function OurGraph({ headerText }) {
    const [graphText, setGraphText] = useState(headerText);

    useEffect(()=>{
     setGraphText(headerText)
    },[headerText])

    // create editable header
    const ourHeader =
        (<foreignObject width='100%' height='40'>
            <div xmlns='http://www.w3.org/1999/xhtml'>
                <FormControl
                    className='modal-input no-style'
                    type='text'
                    value={graphText}
                    onChange={e => setGraphText(e.target.value)}
                    name='subheader'
                    placeholder=''
                />
            </div>
        </foreignObject>);

    // and return
    return (<svg>{ourHeader}</svg>);
 }

此外,更好的方法是將此 state 置於上下文中並從上下文中導出 onChange function 並使用自定義掛鈎對其進行操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM