不确定如何在stackoverflow中将其转换为可重现的示例,但我们有以下React组件,它利用foreignObject
和FormControl
创建SVG图形,该图形具有可编辑的标题文本(可以单击文本进行编辑,也可以键入文本进行编辑
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 text
)时,OurGraph
组件中的SVG文本不会更新为false text
,即使属性值成功更新为false text
。
为什么会这样?我们如何解决这个问题,使属性值的变化反映在SVG的Form控件中?我们认为新的headerText
值会导致const [graphText, setGraphText] = useState(headerText);
为graphText
设置新值,但是当headerText
属性从true text
更改为false text
时,graphText
没有发生变化。
Edit-尽管立即setState看起来像是反模式(),但是我们需要graphText作为state中的变量,因为它在FormControl中更新,并且我们希望prop值headerText
是graphText
的默认值。我们想要用在headerText
中传递的新的prop值来覆盖从FormControl
设置的graphText
中的任何值。
1条答案
按热度按时间wj8zmpe11#
这是一个典型的反模式例子。React不重新初始化状态。为了使它工作,你可以做以下事情:
此外,一个更好的方法是将这个状态放到上下文中,然后从上下文中导出onChange函数,并使用自定义钩子来操作它。