使用包装组件时的 useState 和 onChange 问题

问题描述 投票:0回答:1

我想创建一个灵活的模式包装器,我可以在其中放置交互式组件。在这种情况下,我想将输入放入模态中,这会影响表单的整体状态。

形式:

  const [formInfo, setFormInfo] = useState({});
  const [modalMetadata, setModalMetadata] = useState({});
  const [modalContents, setModalContents] = useState({});
  const [modalShow, setModalShow] = useState(false);

...
        return <ModalWrapper modalIsOpen={modalShow} closeModal={() => {setModalShow(false)}} contents={modalMetadata}>
            {modalContents}
          </ModalWrapper>
          <button onClick={
            setModalShow(true);
            setModalMetadata({
              contentLabel: "",
              title: "Are you sure?",
              buttons: [
                {
                  onClick: () => setModalShow(false),
                  content: "Cancel"
                },
                {
                  onClick: () => submitForm(),
                  content: "Confirm"
                }
              ],
            })}

            setModalContents(<div><h4>blahblahblah</h4>
              {inputTitles.map((k) => <div key={"field-"+ k}>
                  <div>
                  <input 
                    type='text'
                    onChange={i => {
                      console.log(i.target.value);
                      console.log(formInfo)
                      console.log({...formInfo, ["field-" + k]: i.target.value})
                      setFormInfo( formInfo => {return {...formInfo, ["field-" + k]: i.target.value}})
                    }}
                  />
                  <span></span>  
                  </div>
                  <label>${k}</label>
                </div>)}
             </div>);



}>

包装纸:

import Modal from 'react-modal';    


export default function ModalWrapper({ modalIsOpen, closeModal, contents, children }) {
  
    return (
      <div>
        <Modal
          isOpen={modalIsOpen}
          onRequestClose={closeModal}
          contentLabel={contents.contentLabel}
        >
          <h2>{contents.title}</h2>
            {children}
          <div>
            {(contents?.buttons ?? []).map((i, idx) => <button className={i.className} key={"button-" + idx} onClick={i.onClick}>{i.content}</button>)   }

          </div>
        </Modal>
      </div>
    );
}

(为简洁起见,删除了 CSS 和不相关的变量)

虽然大多数调试控制台语句返回预期值并且按钮按计划工作,但我注意到

formInfo
没有更新。
setFormInfo
在模式内容中未按预期工作的原因是什么?

我在网上查找,发现了该机制工作的多个示例(12),它们将通过另一个组件的子组件传递 React hook,但我无法复制我遇到的错误。对 React Children 和 React hooks 的本质有更好了解的人会知道出了什么问题吗?

[2] 我尝试将 onChange 属性添加到作为独立输入元素和 Avatar 元素给出的示例中,但它按计划工作。

reactjs react-hooks
1个回答
0
投票

React 中状态的工作很多时候有点令人困惑。 useState 钩子更新状态变量,其更新值将在组件的下一次渲染中可用。

例如,如果你这样做

const [text, setText] = useState("");

setText("text");
console.log(text);

console.log 会将文本值打印为空字符串。在下一个渲染中,您将能够在控制台中看到“文本”。

设置要传递给子组件的状态变量的最佳方法是在 useEffect 挂钩中设置它们。

© www.soinside.com 2019 - 2024. All rights reserved.