[英]React: How to setState in child component from parent component?
我是 React 的新手,正在嘗試設置一個 Bootstrap 模式來顯示警報消息。
在我的父 App.js 文件中,我有一個錯誤處理程序,它向 Modal.js 組件發送一個觸發模態顯示的道具,例如:
在 App.js 上:
function App() {
const [modalShow, setModalShow] = useState(false);
// Some other handlers
const alertModalHandler = (modalMessage) => {
console.log(modalMessage);
setModalShow(true);
}
return (
// Other components.
<AlertModal modalOpen={modalShow}/>
)
}
在 Modal.js 上:
import React, { useState } from "react";
import Modal from "react-bootstrap/Modal";
import "bootstrap/dist/css/bootstrap.min.css";
const AlertModal = (props) => {
const [isOpen, setIsOpen] = useState(false);
if (props.modalOpen) {
setIsOpen(true);
}
return (
<Modal show={isOpen}>
<Modal.Header closeButton>Hi</Modal.Header>
<Modal.Body>asdfasdf</Modal.Body>
</Modal>
);
};
export default AlertModal;
但是,這不起作用。 我得到錯誤:
Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
如果我將 Modal 組件更改為“啞”組件並直接使用道具,例如:
const AlertModal = (props) => {
return (
<Modal show={props.modalOpen}>
<Modal.Header closeButton>Hi</Modal.Header>
<Modal.Body>asdfasdf</Modal.Body>
</Modal>
);
};
它確實有效,但我也想在 Modal.js 組件級別更改顯示/隱藏 state,例如在其中處理模式關閉按鈕的東西。
我不明白為什么會中斷?
這是否意味着我必須在父 App.js 級別處理模態關閉 function ?
編輯 - 完整的 app.js 內容
import React, { useState } from 'react';
import './App.css';
import 'bootstrap/dist/css/bootstrap.css';
import AddUserForm from './components/addUserForm';
import UserList from './components/userList';
import AlertModal from './components/modal';
function App() {
const [users, setUsers] = useState([]);
const [modalShow, setModalShow] = useState(false);
const addPersonHandler = (nameValue, ageValue) => {
console.log(nameValue, ageValue);
setUsers(prevUsers => {
const updatedUsers = [...prevUsers];
updatedUsers.unshift({ name: nameValue, age: ageValue });
return updatedUsers;
});
};
const alertModalHandler = (modalMessage) => {
console.log(modalMessage);
setModalShow(true);
}
let content = (
<p style={{ textAlign: 'center' }}>No users found. Maybe add one?</p>
);
if (users.length > 0) {
content = (
<UserList items={users} />
);
}
return (
<>
<div className="container">
<div className="row">
<div className="col-md-6 offset-md-3">
<AddUserForm onAddPerson={addPersonHandler} fireAlertModal={alertModalHandler}/>
</div>
</div>
<div className="row">
<div className="col-md-6 offset-md-3">
{content}
</div>
</div>
</div>
<AlertModal modalOpen={modalShow}/>
</>
);
}
export default App;
在你的 modal.js
你應該把
if (props.modalOpen) {
setIsOpen(true);
}
在使用效果中。
React.useEffect(() => {if (props.modalOpen) {
setIsOpen(true);
}}, [props.modalOpen])
你永遠不應該像那樣調用setState
。 如果您這樣做,它將在每個渲染上運行並觸發另一個渲染,因為您更改了 state。 您應該將setModalShow
與 if 子句一起放在useEffect
中。 例如:
useState(() => {
if (modalOpen) {
setIsOpen(true);
}
}, [modalOpen])
請注意,我還從props
中重構了modalOpen
。 這樣useEffect
只會在modalOpen
更改時運行。
如果您已經向AlertModal組件發送了一個名為modalShow的 state ,則沒有理由使用另一個 state ,它執行相同的操作,例如isOpen 。
每當更改modalShow時,它都會導致AlertModal組件的重新渲染,因為您更改了它的 state,然后如果該道具為真,則在內部設置另一個 state,當您設置isOpen時會導致另一個不需要的重新渲染。 然后,在每次重新渲染時,如果 props.showModal 沒有改變(並且仍然是真的),你會一次又一次地觸發setIsOpen 。
如果您想控制AlertModal中的模式打開/關閉,我將執行以下操作:
<AlertModal modalOpen={modalShow} setModalOpen={setModalShow}/>
將showModal state 的集合 function 傳遞給模態組件,然后根據需要使用它。 例如,在 onClick 處理程序中。
模態的.js:
import React, { useState } from "react";
import Modal from "react-bootstrap/Modal";
import "bootstrap/dist/css/bootstrap.min.css";
const AlertModal = (props) => {
const onClickHandler = () => {
props.setModalOpen(prevState => !prevState)
}
return (
<Modal show={props.modalOpen}>
<Modal.Header closeButton>Hi</Modal.Header>
<Modal.Body>asdfasdf</Modal.Body>
</Modal>
);
};
export default AlertModal;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.