[英]React - Call function from 'sibling' component
這是我當前的 model,請查看
import component 1 & 2
export default class App extends Component {
render() {
return (
<Component1/>
<Component2/>
);
}
}
在組件 1 中,我有一個 function:運行此 function 后的 pushData(),我想在組件 2 上使用 fetchData() 執行下一步,但我找不到從 1 引用 2 的方法,因為它們不是父級-孩子?!
這可以通過多種方式完成,考慮到上面共享的代碼具有基於 Class 的實現,我建議采用以下解決方案。
現在 Component1 將擁有自己的 function 來推送數據,我們稱其為 function pushData 。 一旦推送數據的邏輯結束,調用傳遞的 prop function dataPushed 。 此道具將使用當前狀態更新父級 state,即數據已推送,並將 state 變量設置為 true。
現在這個state這個變量已經傳給了Component2,在Component2中使用ComponentDidUpdate。我們可以知道從Component1傳來的dataPush的state,如果為真,就可以調用Component2內部的function來獲取數據。
獲取數據后,立即調用傳遞給此 Component2 的 prop 讓父級知道已獲取最新數據,並將 dataPushed 的父級變量 state 設置為 false。
忽略 function 和使用的變量名,隨意使用你的。
我用代碼創建了一個沙箱,
https://codesandbox.io/s/affectionate-forest-5kc68?file=/src/App.js
我希望這能解決你的問題。 如果您仍然對上述任何解釋感到困惑或不清楚,請告訴我。
從架構上講,您嘗試做的不是一個好主意。
例如,如果您更改具有您要使用的 function 的組件,您需要記住更新使用此 function 的任何依賴項。這變得難以維護。
React 道具實際上使使用依賴注入模式解決這個問題變得非常容易。 如果你不熟悉依賴注入,它本質上意味着依賴是自上而下的,需要這些依賴的組件不知道這個依賴在哪里,也不會出去獲取它們。 它只是獲取傳入的依賴項。
您可以將 function 提升一個級別並讓它存在於父組件中,而不是嘗試使用存在於同級組件中的方法。 與 state 相同。
想象一下這位家長:
class Container extends React.Component {
state = {
counter: 0
};
reallyCoolFunction = () => {
this.setState({ counter: this.state.counter + 1 });
};
render() {
return (
<>
<Cool
counter={this.state.counter}
doCoolThing={this.reallyCoolFunction}
/>
<Wannabe doCoolThing={this.reallyCoolFunction} />
</>
);
}
}
上面的Container
組件創建了 function 並將其傳遞給兩個組件。 然后每個組件會在需要時調用 function,例如:
class Wannabe extends React.Component {
handleClick = () => {
this.props.doCoolThing();
};
render() {
return (
<div>
<h2>Wannabe</h2>
<button onClick={this.handleClick}>click</button>
</div>
);
}
}
然后在你的應用程序中擁有 function 的組件得到傳遞的相關道具:
class Cool extends React.Component {
handleClick = () => {
this.props.doCoolThing();
};
render() {
return (
<div>
<h2>Cool</h2>
<p>{this.props.counter}</p>
<button onClick={this.handleClick}>click</button>
</div>
);
}
}
如果您的應用程序正在增長並且您計划對其進行一段時間的開發,您可能需要考慮實施 state 管理解決方案,例如Redux 。 使state管理更簡單。
如果您要使用功能組件而不是 class 組件,則可以使用第三種選擇,那就是構建您自己的自定義掛鈎。 如果您還不熟悉鈎子,那可能有點學習曲線。 您可以閱讀React hooks 文檔了解如何做到這一點。
我已經創建了一個描述的容器組件和子組件示例的演示。 在此示例中,它們都能夠更新Cool
組件中顯示的 state: https://codesandbox.io/s/dry-hill-r425r?file=/src/App.js
您必須傳遞來自父級的回調,該回調將在您的第一個 function 執行后調用,更新父級的 state 然后將道具傳遞給第二個組件以通知它。
import React from "react";
class Component1 extends React.Component {
componentDidMount() {
// execute your first function here
if (this.props.onPushData) {
this.props.onPushData();
}
}
render() {
return <p>Component1</p>;
}
}
class Component2 extends React.Component {
componentDidUpdate(prevProps) {
if (prevProps.dataPushed !== this.props.dataPushed) {
if (this.props.dataPushed) {
// execute your second function here
}
}
}
render() {
return <p>Component2</p>;
}
}
export default class extends React.Component {
state = {
dataPushed: false
}
handleDataPush = () => {
this.setState({ dataPushed: true })
}
render() {
return (
<div>
<Component1 onPushData={this.handleDataPush} />
<Component2 dataPushed={this.state.dataPushed} />
</div>
);
}
}
這是一個 例子
在 component1 中訪問 component2 的 function 的一種方法是使用refs
。
代碼片段:
export default class App extends React.Component {
ref = React.createRef();
render() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Component1 comp2Ref={this.ref} />
<Component2 ref={this.ref} />
</div>
);
}
}
// Component1.js
export default class Component1 extends React.Component {
pushData = () => {
// make the first api call..
console.log("comp 1 fun");
// now call component2 function
console.log(this.props);
this.props.comp2Ref.current.fetchData();
};
render() {
return (
<div className="App">
<h1>component 1</h1>
<button onClick={this.pushData}>push data button</button>.
</div>
);
}
}
// Component2.js
export default class Component2 extends React.Component {
fetchData = () => {
console.log("comp 2 fun");
};
render() {
return (
<div className="App">
<h1>component 2</h1>
</div>
);
}
}
處理您的場景的最佳方法是將fetchData
function 提升到父級並將其作為 prop 傳遞給component2
。
像這樣
export default class App extends React.Component {
state = {
data: []
};
fetchData = () => {
// fetch the data and update the state(data) and pass it as prosp in component 2
console.log("comp 2 fun");
};
render() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Component1 fetchData={this.fetchData} />
<Component2 data={this.state.data} fetchData={this.fetchData} />
</div>
);
}
}
// Component 1 pushData function
...
pushData = () => {
// make the first api call..
console.log("comp 1 fun");
// now call component2 function
console.log(this.props);
this.props.fetchData();
};
...
從長遠來看,我建議您將Redux添加到當前堆棧,React 在使用大層次結構組件進行擴展以及與后端 API 集成方面存在局限性。
所以如果你正在尋找一個真正的項目在生產中,是時候切換到React-Redux
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.