[英]How do I change the values of a state of a parent component whenever a child component renders?
我正在學習 React,我試圖弄清楚如何在子組件呈現時更改父組件的狀態。
這是我到目前為止所做的:
這是一個代碼和框https://codesandbox.io/s/modest-almeida-f9spo?file=/src/App.js
這是代碼
import React, { useState, useEffect } from "react";
import "./styles.css";
import data from "./data";
export default function App() {
const [total, setTotal] = useState({
price: 0,
discount: 0
});
function calcTotal(prop, value) {
const newTotal = { ...total };
newTotal[prop] += value;
setTotal(newTotal);
}
return (
<div className="App">
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{data.map((item) => (
<Item
key={item.id}
data={item}
calcTotal={calcTotal}
total={total}
/>
))}
</tbody>
<Total total={total} />
</table>
</div>
);
}
function Item(props) {
const item = props.data;
const calcTotal = props.calcTotal;
useEffect(() => {
calcTotal("price", item.price);
calcTotal("discount", item.discount);
}, []);
return (
<tr>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.price}</td>
</tr>
);
}
function Total(props) {
const total = props.total;
return (
<tfoot>
<tr>
<th colSpan="2">Total Price: </th>
<td>{total.price}</td>
</tr>
<tr>
<th colSpan="2">Total Discount: </th>
<td>{total.discount} </td>
</tr>
</tfoot>
);
}
React 並不真的希望您擁有雙向數據流。 但是,可以使用新的雙向綁定助手: https : //reactjs.org/docs/two-way-binding-helpers.html
但是請記住,由子項引起的父項的更改可以使父項重新渲染,這反過來又可以使子項發生更改並導致無限循環。
您還可以查看 Redux ( https://redux.js.org/ ) 等庫,以獲得每個組件都可以訪問和訂閱事件的全局存儲。
您應該考慮使用 React Redux 來管理此類行為。
但是,您可以將回調函數從父組件傳遞給子組件。
例子:
class ChildComponent extends React.Component {
constructor(props)
{
super(props);
}
componentDidMount()
{
props.onChildRendered();
}
render() {
return (
);
}
}
class ParentComponent extends React.Component {
constructor(props)
{
super(props);
this.state = {
childRendered = false;
}
}
onChildRendered = () => {
this.setState({
childRendered: true
});
}
render() {
return (
<ChildComponent onChildRendered={ this.onChildRendered }/>
);
}
}
在你聲明一個函數的父組件中,只要它被觸發,你就會在這個函數中改變父狀態。
然后將該函數作為 prop 傳遞給子組件。
當子組件掛載時,您會觸發作為 prop 傳遞的函數。
這會觸發父組件中的函數並更改其狀態,從而導致重新渲染。
這永遠不會導致無限循環,因為子組件中的 componentDidMount() 僅在組件的初始安裝時觸發。
應謹慎使用此技術,因為有更好的方法來管理事物,例如使用 Redux 等狀態管理中間件。
如果僅通知父級已呈現子級,這可能是可以接受的,但這是普遍的做法,並鼓勵數據從父級流向子級。
父組件中需要的子組件中的任何數據通常都會向上移動到父組件。 向上移動狀態的過程稱為“提升狀態”。
在父組件中計算 totalPrice 和 Discount
試試下面的代碼:
import React, { useState, useEffect } from "react";
import "./styles.css";
import data from "./data";
export default function App() {
const [total, setTotal] = useState({
price: 0,
discount: 0
});
useEffect((prop) => {
calcTotal();
}, []);
function calcTotal() {
const newTotal = { ...total };
data.forEach((item) => {
newTotal.price += item.price;
newTotal.discount += item.discount;
});
setTotal(newTotal);
}
return (
<div className="App">
<div>{JSON.stringify(data)}</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{data.map((item) => (
<Item key={item.id} data={item} total={total} />
))}
</tbody>
<Total total={total} />
</table>
</div>
);
}
function Item(props) {
const item = props.data;
return (
<tr>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.price}</td>
</tr>
);
}
function Total(props) {
const total = props.total;
return (
<tfoot>
<tr>
<th colSpan="2">Total Price: </th>
<td>{total.price}</td>
</tr>
<tr>
<th colSpan="2">Total Discount: </th>
<td>{total.discount} </td>
</tr>
</tfoot>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.